msc
msc

Reputation: 34658

Undefined behaviour in repeated use of prefix ++ operator

I read this answer about undefined behaviour, where I saw following statement:

++++++i;     // UB, parsed as (++(++(++i)))

I don't think it is undefined behaviour. I have a doubt, Is it really UB in C++? If yes, then How?

Also, I made program and compiled using g++ prog.cpp -Wall -Wextra -std=gnu++1z -pedantic command, it's working fine without any warning. It's give an expected output.

#include <iostream>
using namespace std;

int main()
{
    int i = 0;
    cout<<++++++i<<endl;
}

Upvotes: 23

Views: 1534

Answers (2)

user9041001
user9041001

Reputation: 376

In C++03 it is undefined behavior. In C++11 it is not. There is no sequence point between the various pre-increments. If i was a user-defined type, it would be well-defined behavior because then there would be a function call (a sequence point).

In C++11, the idea of sequence points was replaced with sequenced before/sequenced after. Defect 637 (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#637) provides an example of a previously undefined construct becoming well-defined (i = ++i + 1).

To understand why it's not undefined behavior, let's look at the pieces we need. ++i is equivalent to i = i + 1 (except i is evaluated only once). Further if we substitute i = i + 1 with inc, ++(i = i + 1) becomes inc = inc + 1.

[expr.ass] states:

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.

Thus the assignment in i = i + 1 is sequenced before value computation of inc; however, the assignment in inc = inc + 1 is sequenced after value computation of inc. There is no undefined behavior because the assignments are sequenced.

Upvotes: 36

David Schwartz
David Schwartz

Reputation: 182829

Sometimes behavior is undefined even though it's hard to imagine how it could be mishandled. But pre-C++11, this was undefined because the same object is modified multiple times without an intervening sequence pointed.

One could imagine a compiler that "optimized" the code by consolidating all the modifications to i. Thus each increment winds up incrementing the original value. But that's not the point. UB is UB if the standard says so. It doesn't matter whether or not we can imagine ways it can fail.

Upvotes: 9

Related Questions