Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequence points - is this gcc warning a bug?

Take this toy program:

int main() 
{
  int a = 1;
  a = ++a ;
}

Compilation under gcc 9.3 (or even trunk) with -Wall -std=c++17 outputs:

<source>:4:5: warning: operation on 'a' may be undefined [-Wsequence-point]
    4 |   a = ++a ;
      |   ~~^~~~~

I'm aware that in the past this indeed was an issue, but a different answer to the same SO question points to the part of the C++17 standard that was fixed to indicate that in an assignment operations the rhs is sequenced before the actual assignment:

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.

So is this warning indeed bogus or am I missing something?

like image 513
Ofek Shilon Avatar asked Mar 30 '20 19:03

Ofek Shilon


People also ask

How do I turn off GCC warnings?

To answer your question about disabling specific warnings in GCC, you can enable specific warnings in GCC with -Wxxxx and disable them with -Wno-xxxx. From the GCC Warning Options: You can request many specific warnings with options beginning -W , for example -Wimplicit to request warnings on implicit declarations.

How do I enable all warnings in GCC?

For GCC, copying from the full list of warnings provided by this tool for your compiler version appears to be the only way to ensure that all warnings are turned on, since (unlike Clang) GCC does not provide -Weverything . The tool appears to parse the actual c.


2 Answers

As already mentioned in the other answer, the code is well-behaved and the message a false-positive for C++17, but I want to add that GCC is purposefully still warning about it.

The GCC documentation states about the -Wsequence-point warning flag (enabled by -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++.

So it is intended that this program gives that warning.

like image 29
walnut Avatar answered Sep 21 '22 17:09

walnut


Yes, this is a bug. Per [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 ]

emphasis mine

There is now a sequence point between the increment and the assignment and the code has well defined behavior. Their warning heuristics needs to be updated to take this new feature into account.

like image 93
NathanOliver Avatar answered Sep 20 '22 17:09

NathanOliver