1

In the following C++ code is there a difference between the values of x and y at the end?

const int LoopLength = 100;
unsigned short x = 0;
for (int i = 0; i < LoopLength; i++)
{
    x = ++x % 2;
    cout << x;
}

cout << endl;

unsigned short y = 0;
for (int i = 0; i < LoopLength; i++)
{
    ++y = y % 2;
    cout << y;
}

cout << endl << (x == y) << endl;

Coverity (static-analysis tool) claims that the order in which the side-effects take place is undefined with a line like x = ++x % 2;. I'm unsure if I should worry about it.

PerryC
  • 1,233
  • 2
  • 12
  • 28
  • 1
    http://stackoverflow.com/questions/14005508/so-why-is-i-i-1-well-defined-in-c11 – Steephen Jul 17 '15 at 15:44
  • The `x` line is not bad, though you should put brackets around the bit you want to happen first, if the standard leaves the order undefined. The `y` assignment, however, looks like a disaster waiting to happen. Does that even compile? – underscore_d Jul 17 '15 at 15:44
  • 2
    @underscore_d The first line should be well defined due to the rule Stephen's linked answer. The preincrement operator returns a glvalue which can be assigned to so it is perfectly fine syntax-wise to put it on the left hand side of the assignment operator. I get the feeling that undefined sequencing around the operator will make the overall behavior undefined, though. – IllusiveBrian Jul 17 '15 at 15:50
  • Thanks - I was just reading through explanations of why it can yield a valid lvalue and came back to edit my comment, but I was too late. Learn something new every day :) I think I personally would avoid it though, unless I was writing something for the IOCCC! – underscore_d Jul 17 '15 at 15:51
  • ++y = y % 2; may result in undefined behavior. – Satish Chalasani Jul 17 '15 at 16:11
  • 1
    @underscore_d It compiles =/. I just talked to a coworker who shuddered after looking at the y line though. – PerryC Jul 17 '15 at 16:37

1 Answers1

3

Both forms are totally undefined prior to C++11 because they both write to the same memory location without an intervening sequence point.

According to the linked question So why is i = ++i + 1 well-defined in C++11? the first form is legal in C++11, due to more restricted sequencing of writes.

I believe that the second case is not well defined as the order of evaluation of the operands to = are not specified.

Luckily all these questions can be avoided by never ever writing code that anywhere near resembles this. Your future code maintainers will thank you and send you gifts from the future.

Community
  • 1
  • 1
Mark B
  • 95,107
  • 10
  • 109
  • 188