Ist "(i) = 1" in Standard C illegal?

8

Ich schreibe einen C-Compiler, der diesem Standard folgt , und wenn ich Anweisungen wie diese analysiere:

int i;
(i) = 1;

Mein Compiler meldet einen Fehler, der darauf hinweist, dass (i)es sich um einen Wert handelt, der nicht zuweisbar sein sollte.

Ich habe den Code und die Regeln überprüft und Folgendes festgestellt: In der Semantik des Zuweisungsausdrucks:

Ein Zuweisungsoperator muss einen modifizierbaren Wert als linken Operanden haben.

Ein Zuweisungsausdruck hat den Wert des linken Operanden nach der Zuweisung, ist jedoch kein l-Wert.

In meinem Fall gibt es zwei Zuweisungsausdrücke: (i) = 1und iin Klammern. Das (i)sollte also ein Wert sein.

Meine Frage lautet also: Ist (i) = 1dieser C-Standard illegal?

Ravenisadesk
quelle
1
Es ist immer noch ein Wert, die Klammern ändern das nicht.
Jeff Mercado
1
Hallo zusammen, bitte weisen Sie darauf hin, welche Regel im Standard legal ist. Mein Compiler hält sich strikt an die Regel.
Ravenisadesk
iin Klammern steht kein Zuweisungsausdruck. Zuweisungsausdruck bedeutet nicht "Ausdruck, der an einer Zuweisung beteiligt ist" oder irgendetwas anderes, wo (i)dies qualifiziert wäre. Zuweisungsausdrücke sind Zuweisungen .
user2357112 unterstützt Monica
@ user2357112 iist ein Zuweisungsausdruck wird der AST Baum EXPRESSION-> ASSIGNMENT_EXPRESSION-> CONDITIONAL_EXPRESSION-> LOGICAL_OR_EXPRESSION-> CAST_EXPRESSION-> UNARY_EXPRESSION-> POSTFIX_EXPRESSION-> PRIMARY_EXPRESSION-> IDENTIFIER
ravenisadesk
@reavenisadesk: Ein assignment-expressionGrammatik-Nichtterminal ist nicht dasselbe wie ein Zuweisungsausdruck. In etwa assignment-expressionist ein Zuweisungsausdruck oder etwas mit höherer Priorität.
user2357112 unterstützt Monica

Antworten:

8

Um n1570 (den letzten C11-Standardentwurf vor der Veröffentlichung) zu zitieren:

6.5.1 Primäre Ausdrücke (Hervorhebung von mir)

5 Ein Ausdruck in Klammern ist ein primärer Ausdruck. Sein Typ und sein Wert sind identisch mit denen des nicht parästhesierten Ausdrucks . Es ist ein l-Wert, ein Funktionsbezeichner oder ein ungültiger Ausdruck, wenn der nicht in Klammern gesetzte Ausdruck ein l-Wert, ein Funktionsbezeichner oder ein nichtiger Ausdruck ist.

iist ein lWert, so wie oben beschrieben (i). Und um Ihre Frage zu beantworten, ist der Ausdruck (i) = 1gültig C.

Geschichtenerzähler - Unslander Monica
quelle
Ich habe Probleme, sehen wir uns die BNF des primären Ausdrucks in Klammern an: ( expression )Der Typ und der Wert sind also identisch mit expressionund expressionsind ein assignment expression, und das assignment expressionist ein primary expression, wird einfach iwie assignment expressionendlich behandelt, also sollte es der Regel von assignment expressionat folgen Zuletzt, also sollte es ein Wert sein, denke ich.
Ravenisadesk
1
@reavenisadesk - Außer ganz klar, Schwarz auf Weiß ist kein Wert. Oder sagen Sie, i = 1ist auch ungültig?
Geschichtenerzähler - Unslander Monica
Ich denke, das i = 1ist aus diesem Grund gültig: assignment-expression: unary-expression assignment-operator assignment-expressionIn dem Fall werde i = 1ich behandelt als unary-expression, was ein Wert ist, nicht assignment expression, ich denke, Ihr i = 1Beispiel ist nicht der Fall.
Ravenisadesk
2
@reavenisadesk: Die Grammatik sagt nicht, was Dinge lWerte oder rWerte sind. Die Semantik tut es. Für einen Zuweisungsausdruck sagt C 6.5.16 3 (direkt unter der Überschrift „Semantik“) einen Zuweisungsausdruck (eine Phrase, die den mit einem Zuweisungsoperator gebildeten Ausdruck beschreibt, nicht einen Zuweisungsausdruck , der ein Token in der Grammatik ist ) ist kein Wert. Es heißt nicht, dass das Grammatik-Token für Zuweisungsausdrücke kein Wert ist.
Eric Postpischil
1
@reavenisadesk - Eric hat es viel beredter erklärt als ich. Außerdem scheint es mir, dass Sie hier zu (i)Unrecht aufgreifen. Der gleiche Punkt über die Semantik gilt für jede Art von Ausdruck.
Geschichtenerzähler - Unslander Monica
0

StoryTeller hat bereits erklärt, wo in der Norm, warum für Ihr Beispiel der Ausdruck (i)immer noch ein Wert ist, aber ich glaube, Sie werden ohne Grund an die Spezifikation gehängt. Erlauben Sie mir daher, Ihre Bedenken auszuräumen.

Ich habe den Code und die Regeln überprüft und Folgendes festgestellt: In der Semantik des Zuweisungsausdrucks:

Ein Zuweisungsoperator muss einen modifizierbaren Wert als linken Operanden haben.

Ein Zuweisungsausdruck hat den Wert des linken Operanden nach der Zuweisung, ist jedoch kein l-Wert.

Das gesamte Zitat bezieht sich auf den Zuweisungsausdruck als Ganzes, nicht auf die lhs oder rhs.

"Ein Zuweisungsoperator muss einen modifizierbaren Wert als linken Operanden haben." gibt an, dass das lhs ein modifizierbarer l-Wert sein muss.

"Ein Zuweisungsausdruck hat den Wert des linken Operanden nach der Zuweisung, ist jedoch kein l-Wert." gibt an, dass der gesamte Zuweisungsausdruck selbst als Ergebnis den Wert von lhs hat und selbst ein r-Wert ist.

Das Folgende ist also alles wahr:

int i;
  i <- modifiable lvalue

(i) = 1;
  (i) <- modifiable lvalue (per StoryTeller's answer)
  1 <- rvalue
  ((i) = 1) <- rvalue

Warum ist das so wichtig? Folgendes berücksichtigen:

int i = 0, j = 0, k = 0;
i = j = k = 1;
// parsed as `i = (j = (k = 1))`
// the expression `k = 1` has the value `1` and is an rvalue
// the expression `j = (k = 1)` has the value `1` and is an rvalue

(i = 2) = 3;
// is invalid, the expression `i = 2` is an rvalue, but it may not be the lhs of the assignment

In meinem Fall gibt es zwei Zuweisungsausdrücke: (i) = 1und iin Klammern. Das (i)sollte also ein Wert sein.

Nein, das ist falsch. (i) = 1ist der einzige Zuweisungsausdruck. Es gibt zwei Unterausdrücke (einen Bezeichner in Klammern (i)und eine numerische Konstante 1).

Jeff Mercado
quelle
0

Diese Antwort ist von @Eric Postpischil inspiriert.

die Produktion von a assignment-expressionist:

<assignment-expression> ::= <conditional-expression>
                          | <unary-expression> <assignment-operator> <assignment-expression>

In der Norm assignment expressionbedeutet das spezifische Mittel Ausdrücke mit Zuweisungsoperatoren. Damit:

<conditional-expression> is not an assignment expression
<unary-expression> <assignment-operator> <assignment-expression> is an assignment expresssion

so die Regel:

Ein Zuweisungsausdruck hat den Wert des linken Operanden nach der Zuweisung, ist jedoch kein l-Wert.

passt nur für die Produktion <unary-expression> <assignment-operator> <assignment-expression>, nicht für<conditional-expression>

in dem Beispiel (i) =1, iist eine , <assignment-expression>aber nicht ein assignment expression, es ist <conditional-expression>also ein lvaule so ist (i)ein L - Wert.

Ravenisadesk
quelle