`(i) = 1` 在标准 C 中是非法的吗?
Is `(i) = 1` illegal in standard C?
我正在编写遵循 this standard 的 C 编译器,如果我像这样解析语句:
int i;
(i) = 1;
我的编译器将报告一个错误,指出 (i)
是一个右值,不应赋值。
我检查了代码和规则,发现了这个:
在赋值表达式语义中:
An assignment operator shall have a modifiable lvalue as its left
operand.
An assignment expression has the value of the left operand after the
assignment, but is not an lvalue.
在我的例子中,有两个赋值表达式:
(i) = 1
和 i
在括号中。所以 (i)
应该是一个右值。
所以我的问题是:
是
(i) = 1
在这个 C 标准中是非法的?
引用n1570(发布前的最后一个C11标准草案):
6.5.1 Primary expressions (emphasis mine)
5 A parenthesized expression is a primary expression. Its type
and value are identical to those of the unparenthesized expression.
It is an lvalue, a function designator, or a void expression if the
unparenthesized expression is, respectively, an lvalue, a function
designator, or a void expression.
i
是一个左值,所以根据上面的内容,(i)
也是。为了回答你的问题,表达式 (i) = 1
是有效的 C.
StoryTeller 已经在标准中解释了为什么对于您的示例,表达式 (i)
仍然是一个左值,但我相信您无缘无故地挂在规范上,所以请允许我尝试解决你的顾虑。
I checked the code and the rules, and found this: in assignment
expression semantics:
An assignment operator shall have a modifiable lvalue as its left
operand.
An assignment expression has the value of the left operand after the
assignment, but is not an lvalue.
整个引用指的是整个赋值表达式,而不是 lhs 或 rhs。
"An assignment operator shall have a modifiable lvalue as its left operand." 声明 lhs 必须是可修改的左值。
"An assignment expression has the value of the left operand after the assignment, but is not an lvalue." 声明整个赋值表达式本身作为结果具有 lhs 的值并且本身是右值。
所以以下都是正确的:
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
In my case, the there are two assignment expressions: (i) = 1
and i
in
parentheses. So the (i)
should be a rvalue.
不,这是不正确的。 (i) = 1
是唯一的赋值表达式。有两个子表达式(一个带括号的标识符 (i)
和一个数字常量 1
)。
这个答案的灵感来自@Eric Postpischil。
一个assignment-expression
的产生是:
<assignment-expression> ::= <conditional-expression>
| <unary-expression> <assignment-operator> <assignment-expression>
在标准中,assignment expression
特定表示带有赋值运算符的表达式。所以:
<conditional-expression> is not an assignment expression
<unary-expression> <assignment-operator> <assignment-expression> is an assignment expresssion
所以规则:
An assignment expression has the value of the left operand after the
assignment, but is not an lvalue.
仅适用于生产<unary-expression> <assignment-operator> <assignment-expression>
,不适用于<conditional-expression>
在示例 (i) =1
中,i
是一个 <assignment-expression>
但不是 assignment expression
,它是一个 <conditional-expression>
所以它是一个 lvaule 所以 (i)
是一个左值。
我正在编写遵循 this standard 的 C 编译器,如果我像这样解析语句:
int i;
(i) = 1;
我的编译器将报告一个错误,指出 (i)
是一个右值,不应赋值。
我检查了代码和规则,发现了这个: 在赋值表达式语义中:
An assignment operator shall have a modifiable lvalue as its left operand.
An assignment expression has the value of the left operand after the assignment, but is not an lvalue.
在我的例子中,有两个赋值表达式:
(i) = 1
和 i
在括号中。所以 (i)
应该是一个右值。
所以我的问题是:
是
(i) = 1
在这个 C 标准中是非法的?
引用n1570(发布前的最后一个C11标准草案):
6.5.1 Primary expressions (emphasis mine)
5 A parenthesized expression is a primary expression. Its type and value are identical to those of the unparenthesized expression. It is an lvalue, a function designator, or a void expression if the unparenthesized expression is, respectively, an lvalue, a function designator, or a void expression.
i
是一个左值,所以根据上面的内容,(i)
也是。为了回答你的问题,表达式 (i) = 1
是有效的 C.
StoryTeller 已经在标准中解释了为什么对于您的示例,表达式 (i)
仍然是一个左值,但我相信您无缘无故地挂在规范上,所以请允许我尝试解决你的顾虑。
I checked the code and the rules, and found this: in assignment expression semantics:
An assignment operator shall have a modifiable lvalue as its left operand.
An assignment expression has the value of the left operand after the assignment, but is not an lvalue.
整个引用指的是整个赋值表达式,而不是 lhs 或 rhs。
"An assignment operator shall have a modifiable lvalue as its left operand." 声明 lhs 必须是可修改的左值。
"An assignment expression has the value of the left operand after the assignment, but is not an lvalue." 声明整个赋值表达式本身作为结果具有 lhs 的值并且本身是右值。
所以以下都是正确的:
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
In my case, the there are two assignment expressions:
(i) = 1
andi
in parentheses. So the(i)
should be a rvalue.
不,这是不正确的。 (i) = 1
是唯一的赋值表达式。有两个子表达式(一个带括号的标识符 (i)
和一个数字常量 1
)。
这个答案的灵感来自@Eric Postpischil。
一个assignment-expression
的产生是:
<assignment-expression> ::= <conditional-expression>
| <unary-expression> <assignment-operator> <assignment-expression>
在标准中,assignment expression
特定表示带有赋值运算符的表达式。所以:
<conditional-expression> is not an assignment expression
<unary-expression> <assignment-operator> <assignment-expression> is an assignment expresssion
所以规则:
An assignment expression has the value of the left operand after the assignment, but is not an lvalue.
仅适用于生产<unary-expression> <assignment-operator> <assignment-expression>
,不适用于<conditional-expression>
在示例 (i) =1
中,i
是一个 <assignment-expression>
但不是 assignment expression
,它是一个 <conditional-expression>
所以它是一个 lvaule 所以 (i)
是一个左值。