序列点 - 这个 gcc 警告错误吗?
Sequence points - is this gcc warning a bug?
收下这个玩具程序:
int main()
{
int a = 1;
a = ++a ;
}
Compilation under gcc 9.3(甚至主干)-Wall -std=c++17
输出:
<source>:4:5: warning: operation on 'a' may be undefined [-Wsequence-point]
4 | a = ++a ;
| ~~^~~~~
我知道 in the past this indeed was an issue, but a different answer to the same SO question 指向 C++17 标准的固定部分,以指示在赋值操作中 rhs 在实际赋值之前排序:
8.18. ... In all cases, the assignment is sequenced after the value
computation of the right and left operands, and before the value computation of the assignment expression.
这个警告真的是假的还是我遗漏了什么?
是的,这是一个错误。每 [expr.ass]/1
The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand. The result in all cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. The right operand is sequenced before the left operand. With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. [ Note: Therefore, a function call shall not intervene between the lvalue-to-rvalue conversion and the side effect associated with any single compound assignment operator. — end note ]
强调我的
增量和赋值之间现在有一个序列点,代码具有明确定义的行为。他们的警告启发式需要更新以将此新功能考虑在内。
正如另一个答案中已经提到的那样,代码运行良好,消息对 C++17 来说是误报,但我想补充一点,GCC 仍然有意对此发出警告。
GCC documentation 声明了 -Wsequence-point
警告标志(由 -Wall
启用):
The C++17 standard will define the order of evaluation of operands in more cases: in particular it requires that the right-hand side of an assignment be evaluated before the left-hand side, so the above examples are no longer undefined. But this option will still warn about them, to help people avoid writing code that is undefined in C and earlier revisions of C++.
所以这个程序是故意发出警告的。
收下这个玩具程序:
int main()
{
int a = 1;
a = ++a ;
}
Compilation under gcc 9.3(甚至主干)-Wall -std=c++17
输出:
<source>:4:5: warning: operation on 'a' may be undefined [-Wsequence-point]
4 | a = ++a ;
| ~~^~~~~
我知道 in the past this indeed was an issue, but a different answer to the same SO question 指向 C++17 标准的固定部分,以指示在赋值操作中 rhs 在实际赋值之前排序:
8.18. ... In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.
这个警告真的是假的还是我遗漏了什么?
是的,这是一个错误。每 [expr.ass]/1
The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand. The result in all cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. The right operand is sequenced before the left operand. With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. [ Note: Therefore, a function call shall not intervene between the lvalue-to-rvalue conversion and the side effect associated with any single compound assignment operator. — end note ]
强调我的
增量和赋值之间现在有一个序列点,代码具有明确定义的行为。他们的警告启发式需要更新以将此新功能考虑在内。
正如另一个答案中已经提到的那样,代码运行良好,消息对 C++17 来说是误报,但我想补充一点,GCC 仍然有意对此发出警告。
GCC documentation 声明了 -Wsequence-point
警告标志(由 -Wall
启用):
The C++17 standard will define the order of evaluation of operands in more cases: in particular it requires that the right-hand side of an assignment be evaluated before the left-hand side, so the above examples are no longer undefined. But this option will still warn about them, to help people avoid writing code that is undefined in C and earlier revisions of C++.
所以这个程序是故意发出警告的。