4

The code:

int a = 0;
a = ++a % 5;

causes the warning:

warning: operation on 'a' may be undefined [-Wsequence-point]
a = ++a % 5;
~~^~~~~~~~~

with various compilers such as gcc when compiling with -Wall

Yet this code, works fine?

int a = 0;
a = (a + 1) % 5;

Why is this a warning, and can it safely be ignored?

Wrapping it in brackets etc. doesn't seem to make the warning go away.

Edit: For clarification, I was using C++17 compiler when seeing these warning messages.

Hex Crown
  • 753
  • 9
  • 22

2 Answers2

9
a = ++a % 5;

a is modified two times. Before C++11, this is undefined behavior — it is not specified that the increment is committed before the assignment. Since C++11, the side effect of the pre-increment on the RHS is guaranteed to be evaluated first, and a is guaranteed to be 1.

a = (a + 1) % 5;

Here, a is only modified one time. The resulted a is guaranteed to be 1.


Per comment: operator precedence does not determine the order of evaluation. Although assignment has higher precedence, the order of evaluation is still unspecified (prior to C++11).

deimus
  • 9,565
  • 12
  • 63
  • 107
L. F.
  • 19,445
  • 8
  • 48
  • 82
  • 1
    For the sake of clearance, what am I missing here ? https://en.cppreference.com/w/cpp/language/operator_precedence Prefix increment has precedence `3` then direct assignment `16`, isn't this guaranteeing increment before assignment ? – deimus May 23 '19 at 07:37
  • @deimus I also wonder the same. I would definitely say a is set to a+1 first, then a is set to (a+1) % 5 later. – unlut May 23 '19 at 07:48
  • @deimus That’s precedence, not evaluate order. – L. F. May 23 '19 at 07:50
  • @unlut See my previous comment. – L. F. May 23 '19 at 07:50
  • Thanks for the reply! Maybe you should include it in your answer. – unlut May 23 '19 at 07:54
  • 1
    @L.F. But still this looks like is a **defined** behavior since `c++11`, see rules `5` and `8` https://en.cppreference.com/w/cpp/language/eval_order. That would be great is OP states which standard he is using. – deimus May 23 '19 at 08:07
  • @unlut Good suggestion. I have updated my answe to reflect that. – L. F. May 23 '19 at 08:09
  • 1
    @L.F. Check my comment, your updates statement looks like is wrong. – deimus May 23 '19 at 08:11
  • @deimus I’m sorry. I took it for post-increment ... I have updated my answer again. – L. F. May 23 '19 at 08:13
2

EDIT:

Before C++11: Because with ++a you're modifying a while you're modifying a through assignment, therefore undefined behavior.

After C++11: See @L.F.'s answer.

Paul Evans
  • 27,315
  • 3
  • 37
  • 54