2

I seem to recall that in C++11, they made some changes to the sequencing behaviour and that now i++ and ++i have different sequencing requirements.

Is f(++i, ++i) still undefined behaviour? What is the difference between f(i++, i++) and f(++i, ++i)?

Christophe
  • 68,716
  • 7
  • 72
  • 138
Puppy
  • 144,682
  • 38
  • 256
  • 465

3 Answers3

7

It's undefined behaviour unless i is a class type. From C++11 1.9/15:

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.

followed by a note to clarify that this does apply to function arguments:

[ Note: Value computations and side effects associated with different argument expressions are unsequenced. —end note ]

Your code modifies the same object twice without sequencing, so by the same paragraph:

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, the behavior is undefined.

If i were a class type, then ++ would call a function, and function calls are always sequenced with respect to each other. So any modifications of scalar objects would be indeterminately sequenced; there's no undefined behaviour, but the result is unspecified.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
3

It's still undefined behaviour:

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, the behavior is undefined.

§1.9 [intro.execution]

and the order of evaluation of function parameters is unsequenced relative to each other.

Christophe
  • 68,716
  • 7
  • 72
  • 138
1

In C++17, it's not undefined. http://en.cppreference.com/w/cpp/language/eval_order#Undefined_behavior

f(++i, ++i); // undefined behavior until C++17, unspecified after C++17

In a function call, value computations and side effects of the initialization of every parameter are indeterminately sequenced with respect to value computations and side effects of any other parameter.

Community
  • 1
  • 1
Tuff Contender
  • 259
  • 4
  • 11
  • To add to this answer: code `int i = 0; f(++i, ++i)` would result in `i == 2` and `f` called with any of the following combination of parameters: (1, 1), (1, 2), (2, 1), (2, 2) – Revolver_Ocelot Sep 06 '17 at 19:38
  • 1
    [@Revolver_Ocelot](https://stackoverflow.com/users/3410396/revolver-ocelot), I think only the calling of `f(1, 2)` and `f(2, 1)` conform to the C++17 standard, as value computations and side effects of the initialization of two parameters should not overlap. – Tuff Contender Sep 06 '17 at 21:22