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) = 1
und i
in Klammern. Das (i)
sollte also ein Wert sein.
Meine Frage lautet also: Ist
(i) = 1
dieser C-Standard illegal?
c
language-lawyer
variable-assignment
rvalue
lvalue-to-rvalue
Ravenisadesk
quelle
quelle
i
in 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 .i
ist ein Zuweisungsausdruck wird der AST Baum EXPRESSION-> ASSIGNMENT_EXPRESSION-> CONDITIONAL_EXPRESSION-> LOGICAL_OR_EXPRESSION-> CAST_EXPRESSION-> UNARY_EXPRESSION-> POSTFIX_EXPRESSION-> PRIMARY_EXPRESSION-> IDENTIFIERassignment-expression
Grammatik-Nichtterminal ist nicht dasselbe wie ein Zuweisungsausdruck. In etwaassignment-expression
ist ein Zuweisungsausdruck oder etwas mit höherer Priorität.Antworten:
Um n1570 (den letzten C11-Standardentwurf vor der Veröffentlichung) zu zitieren:
i
ist ein lWert, so wie oben beschrieben(i)
. Und um Ihre Frage zu beantworten, ist der Ausdruck(i) = 1
gültig C.quelle
( expression )
Der Typ und der Wert sind also identisch mitexpression
undexpression
sind einassignment expression
, und dasassignment expression
ist einprimary expression
, wird einfachi
wieassignment expression
endlich behandelt, also sollte es der Regel vonassignment expression
at folgen Zuletzt, also sollte es ein Wert sein, denke ich.i = 1
ist auch ungültig?i = 1
ist aus diesem Grund gültig:assignment-expression: unary-expression assignment-operator assignment-expression
In dem Fall werdei = 1
ich behandelt alsunary-expression
, was ein Wert ist, nichtassignment expression
, ich denke, Ihri = 1
Beispiel ist nicht der Fall.(i)
Unrecht aufgreifen. Der gleiche Punkt über die Semantik gilt für jede Art von Ausdruck.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.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:
Warum ist das so wichtig? Folgendes berücksichtigen:
Nein, das ist falsch.
(i) = 1
ist der einzige Zuweisungsausdruck. Es gibt zwei Unterausdrücke (einen Bezeichner in Klammern(i)
und eine numerische Konstante1
).quelle
Diese Antwort ist von @Eric Postpischil inspiriert.
die Produktion von a
assignment-expression
ist:In der Norm
assignment expression
bedeutet das spezifische Mittel Ausdrücke mit Zuweisungsoperatoren. Damit:so die Regel:
passt nur für die Produktion
<unary-expression> <assignment-operator> <assignment-expression>
, nicht für<conditional-expression>
in dem Beispiel
(i) =1
,i
ist eine ,<assignment-expression>
aber nicht einassignment expression
, es ist<conditional-expression>
also ein lvaule so ist(i)
ein L - Wert.quelle