int i;
(i) = 1;
我的编译器报告了一个错误,指出(i)
是rvalue,不应该被赋值。
我检查了代码和规则,并发现以下内容: 在赋值表达式语义中:
赋值运算符的左操作数必须是可修改的lvalue。
赋值表达式具有分配后左操作数的值,但不是lvalue。
在我的情况下,有两个赋值表达式:(i) = 1
和带括号的i
。因此,(i)
应该是rvalue。
所以我的问题是:
在这个C标准中,(i) = 1
是否合法?
int i;
(i) = 1;
我的编译器报告了一个错误,指出(i)
是rvalue,不应该被赋值。
我检查了代码和规则,并发现以下内容: 在赋值表达式语义中:
赋值运算符的左操作数必须是可修改的lvalue。
赋值表达式具有分配后左操作数的值,但不是lvalue。
在我的情况下,有两个赋值表达式:(i) = 1
和带括号的i
。因此,(i)
应该是rvalue。
所以我的问题是:
在这个C标准中,(i) = 1
是否合法?
引用n1570(C11标准发布前的最后一份草案):
6.5.1 主表达式(强调是我的)
5 带括号的表达式是主表达式。它的类型和值与不带括号的表达式相同。如果不带括号的表达式分别是lvalue、函数设计者或void表达式,则它是一个lvalue、函数设计者或void表达式。
i
是一个lvalue,因此根据上述规则,(i)
也是一个lvalue。回答您的问题,表达式(i) = 1
是有效的C语言。
i = 1
也是无效的吗? - StoryTeller - Unslander Monica(i)
。有关语义的同样观点适用于每种表达式。 - StoryTeller - Unslander MonicaStoryTeller已经解释了在标准中为什么对于你的例子,表达式(i)
仍然是一个lvalue,但我认为你没有必要因为规范而困扰,所以让我来尝试解决你的问题。
我检查了代码和规则,并发现在赋值表达式语义中:
赋值运算符的左操作数必须是可修改的lvalue。
赋值表达式具有赋值后左操作数的值,但不是lvalue。
整个引用都是指整个赋值表达式,而不是lhs或rhs。
“赋值运算符的左操作数必须是可修改的lvalue。”表示lhs必须是可修改的lvalue。
“赋值表达式具有赋值后左操作数的值,但不是lvalue。”表示整个赋值表达式本身作为结果具有lhs的值,并且本身是rvalue。
因此以下所有内容都是正确的:
int i;
i <- modifiable lvalue
(i) = 1;
(i) <- modifiable lvalue (per StoryTeller's answer)
1 <- rvalue
((i) = 1) <- rvalue
这有什么重要性呢?考虑以下几点:
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
(i) = 1
和括号中的i
。所以(i)
应该是一个右值。(i) = 1
是唯一的赋值表达式。有两个子表达式(一个带括号的标识符(i)
和一个数值常量1
)。这个答案受到了 @Eric Postpischil 的启发。
assignment-expression
的生成如下:
<assignment-expression> ::= <conditional-expression>
| <unary-expression> <assignment-operator> <assignment-expression>
<conditional-expression> is not an assignment expression
<unary-expression> <assignment-operator> <assignment-expression> is an assignment expresssion
因此规则如下:
赋值表达式在赋值后具有左操作数的值,但不是左值。
仅适用于生产<unary-expression> <assignment-operator> <assignment-expression>
,而不适用于<conditional-expression>
在示例(i) =1
中,i
是一个<assignment-expression>
而不是一个assignment expression
,它是一个<conditional-expression>
,因此它是一个左值,所以(i)
是一个左值。
i
不是赋值表达式。赋值表达式并不意味着“参与赋值的表达式”或任何其他(i)
可以符合的内容。赋值表达式就是赋值。 - user2357112i
是一个赋值表达式,AST 树是 EXPRESSION->ASSIGNMENT_EXPRESSION->CONDITIONAL_EXPRESSION->LOGICAL_OR_EXPRESSION->CAST_EXPRESSION->UNARY_EXPRESSION->POSTFIX_EXPRESSION->PRIMARY_EXPRESSION->IDENTIFIER。 - user2269707