-2
size_t i, same_numbers;
string test = "01234567899";

for ( i = same_numbers = 0; i < test.size(); ( ( test[ i++ ] == test[ i ] ) && same_numbers++ ) );

In this code above, in the VS2015 on debug mode, the "same_numbers" var ends with 1 (which is the correct value), but in release mode, it ends with 11. Why this happens?

Thanks!

Nevallem
  • 11
  • 2
  • 1
    `test[ i++ ] == test[ i ]` Undefined behaviour. Good luck, have fun. – Captain Giraffe Dec 20 '15 at 22:34
  • 1
    You added the "undefined-behavior" to your question yourself. Why did you pick that tag, if you didn't understand what it meant? –  Dec 20 '15 at 22:41

1 Answers1

1

Use of

test[ i++ ] == test[ i ]

is the source of your problem. That will evaluate to

test[ i ] == test[ i+1 ]

with the side effect of i = i + 1

if the LHS is evaluated first. It will evaluate to

test[ i ] == test[ i ]

with the side effect of i = i + 1

if the RHS is evaluated first.

If the LHS and RHS are evaluated in parallel, the program will exhibit undefined behavior.

Don't use such code.

Simplify your code to:

// Use i < test.size()-1 since test[i+1] is accessed in loop.
for ( i = same_numbers = 0; i < test.size()-1; ++i )
{
   if ( test[i+1] == test[i] )
      ++same_numbers;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    Or a horrible mess if the LHS and RHS are evaluated in parallel. The behaviour is undefined, not unspecified. It's not limited to the two orders in your answer. –  Dec 20 '15 at 22:38
  • 1
    The nail in the coffin is that the spec explicitly states that the order of evaluating LHS vs RHS is undefined. – Captain Giraffe Dec 20 '15 at 22:39
  • 1
    @CaptainGiraffe If that's all the spec stated, the behaviour *would* be unspecified and this answer would be correct. –  Dec 20 '15 at 22:40
  • @hvd please elaborate. – Captain Giraffe Dec 20 '15 at 22:40
  • 2
    @CaptainGiraffe If merely the *order* were undefined, the *behaviour* would be unspecified because there would only be a finite number of allowed behaviours. It's actually the *behaviour* that's undefined. ([intro.execution]p15: "If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, and they are not potentially concurrent (1.10), the behavior is undefined." -- but that's not very easy to read.) –  Dec 20 '15 at 22:42
  • 1
    Technically `i < test.size()` should work as test will have the null character at the end that shouldn't make this result in a array out of bounds reference, but since you are making the comparison using `test[i+1]` I'd make the limit `i < test.size()-1` just to make it a little clearer. – RyanP Dec 20 '15 at 22:46
  • @hvd Thanks for the ref. I might need to ask a question about undefined/unspecified in the near future. – Captain Giraffe Dec 20 '15 at 22:49