在标准C中,(i)= 1是否非法?

rea*_*esk 8 c variable-assignment rvalue language-lawyer lvalue-to-rvalue

我正在编写遵循此标准的C编译器,如果我解析这样的语句:

int i;
(i) = 1;
Run Code Online (Sandbox Code Playgroud)

我的编译器将报告一个错误,指出该错误(i)是一个右值,不应分配。

我检查了代码和规则,并在赋值表达式语义中发现了这一点:

赋值运算符的左值应为可修改的左值。

赋值表达式具有赋值后的左操作数的值,但不是左值。

在我的情况下,有两个赋值表达式: (i) = 1和i括号中。因此,(i)应该是一个右值。

所以我的问题是:(i) = 1在此C标准中是否 非法?

Sto*_*ica 8

引用n1570(发布前的最新C11标准草案):

6.5.1主要表达(强调我的意思)

5带 括号的表达式是主要表达式。其类型和值与非括号表达式相同。如果未加括号的表达式分别是一个左值,一个函数标记或一个空表达式,则它是一个左值,一个函数标记或一个空表达式。

i是一个左值,因此根据上述情况也是如此(i)。为了回答您的问题,该表达式(i) = 1是有效的C。

  • @reavenisadesk:语法没有说什么是左值或右值。语义确实如此。对于赋值表达式,C 6.5.16 3(仅在“语义”标题下)表示赋值表达式(这是描述由赋值运算符而不是* assignment-expression *构成的表达式的短语,后者是语法)不是左值。它并不表示* assignment-expression *语法标记不是左值。 (2认同)

小智 0

这个答案的灵感来自@Eric Postpischil。

a 的产生assignment-expression是:

<assignment-expression> ::= <conditional-expression>
                          | <unary-expression> <assignment-operator> <assignment-expression>
Run Code Online (Sandbox Code Playgroud)

在标准中,assignment expression具体是指带有赋值运算符的表达式。所以:

<conditional-expression> is not an assignment expression
<unary-expression> <assignment-operator> <assignment-expression> is an assignment expresssion
Run Code Online (Sandbox Code Playgroud)

所以规则:

赋值表达式具有赋值后左操作数的值,但不是左值。

只适合生产<unary-expression> <assignment-operator> <assignment-expression>,不适合<conditional-expression>

在示例中(i) =1,i是 an<assignment-expression>但不是 an assignment expression,它是 a,<conditional-expression>所以它是左值,所以(i)是左值。