undefined behaviour
Hello everybody......
Can anyone help me out in this :
int a=10;
cout << a << endl << a++;
Is this undefined behaviour or not?
Does the order of evaluation of the arguments matter or not?
Rajesh
# 1 Re: undefined behaviour
This is undefined. The compiler is free to evaluate the expressions a and a++ in any order.
# 2 Re: undefined behaviour
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
So, things such as:
i=++i; // illegal : i is modified two times
i+(i++); // illegal value of i read not only to determine the value to be stored.
i=i+i; // legal : value of i only read to determine the value to be stored.
# 3 Re: undefined behaviour
Frankly I don't understand this construction:
i+(i++);
It doesn't have any effect, hence it generates warning C4552: '+' : operator has no effect; expected operator with side-effect.
cilu at 2007-11-9 0:49:43 >

# 4 Re: undefined behaviour
So, things such as:
i=++i; // illegal : i is modified two times
i+(i++); // illegal value of i read not only to determine the value to be stored.
i=i+i; // legal : value of i only read to determine the value to be stored.
Where is quote from?
I just tried all these constructs on my compiler (Sun WorkShop 6 C++ 5.3), with full warnings turned on and no warnings or errors appeared whatsoever. The results make sense (to me anyway) as well.
i=++i; // i is pre-incremented and then assigned back to i (albeit unnecessary) but nonetheless, I see no reason why this would be illegal.
i+(i++); // i is post-incremented. The result of this would simply be a 1-up from what it originally was. Of course, if there were an assignment here you could get different results depending on the compiler (but I see nothing illegal about this either). Let's say i started out as 2 and you had the following statement... x=i+(i++); If the 1st i were evaluated 1st then you would have x=2+(2++). The result would be x equal to 4 and i equal to 3. If the 2nd i were evaluated 1st then the result would be x=3+(2). The result, of course, being x equal to 5 and i again being equal to 3. In fact, my compiler has the later as the result.
sszd at 2007-11-9 0:50:44 >

# 5 Re: undefined behaviour
int a=10;
cout << a << endl << a++;
A function call is a sequence point. cout is not part of the language, but part of the library, so the "<<" operator resolves into function calls and hence becomes a sequence point. So this construct is perfectly fine.
Also, I may be wrong, but I would be very surprised if operator = would not be a sequence point.
So in short, all of SuperKoko's examples seem well defined to me.
# 6 Re: undefined behaviour
Also, I may be wrong, but I would be very surprised if operator = would not be a sequence point.
operator = is not a sequence point.
i+(i++);
It just looks like a code which increments i, and does nothing else (an addition whose value is not used, which produces a warning).
The compiler may produces invalid code, which may crash (of course, i don't think any compiler on the earth do), for undefined behavior.
i+(i++) is undefined, because it modifies a variable and reads its value (not only to determine the value to store) in the same expression between the same sequence points.
Even if most compilers will not have any problem with this expression, some compilers may produces a compilation error "undefined behavior".
i=++i;
i is modified two times (incrementation operator + assignment operator) with no sequence point.
Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.
It is a more strict condition than the simple condition "side effects may occur in any order".
But it probably allow compiler to perform some complex side effects at the same time.
# 7 Re: undefined behaviour
int a=10;
cout << a << endl << a++;
A function call is a sequence point. cout is not part of the language, but part of the library, so the "<<" operator resolves into function calls and hence becomes a sequence point. So this construct is perfectly fine.
Unfortunately, while a function call is a sequence point for the transistion from internal execution to external execution, the order of evaluation for the parameters to that function is still undefined. So if it evaluates to (anything like):
operator<<(cout, operator<<(a, operator<<(endl, a++)));
The point is that the compiler can then evaluate (a), or (operator<<(endl,a++)) in any order. Therefore you can't determine if the top-level a in this situation has been post-incremented or not.
# 8 Re: undefined behaviour
Good point, I hadn't thought about the evaluation of arguments. Also you are right SuperKoko, the assignment operator is not a sequence point.
# 9 Re: undefined behaviour
@freddyflintstone
Even though compiler may evaluate a and a++ in any order.
The original value of a i.e 10 must be used while printing a or a++.
It's only after the cout statement is executed the value of a is incremented
Am i wrong here?
That's why if we write x= a + a++;
x should always give me 20
and only after ;(next sequence point) a is incremented.
Are () and '+' also sequence points?
# 10 Re: undefined behaviour
I understand that :
cout << a << a++;
is undefined behaviour because there are 2 sequence points(2 function calls)
so 'a' will be evaluated seperately and 'a++' will be evaluated sepeartely(and would have incremented the a's value by 1)
but the order in which they are evaluated makes it undefined.
But in the case :
x= a + a++ ;
There is only one sequence point ';' Right?
So the value of 'a' will not be incremented only in the next sequence point
so i don't understand WHY this is undefined behaviour?
# 11 Re: undefined behaviour
Running the following on a Sun WorkShop 6 C++ 5.3 compiler generates the following results...
int a = 10;
cout << a << " " << a++;
11 10
and...
int a = 10;
x = a + a++;
cout << x << " " << a;
21 11
Another compiler and/or another platform may generate sightly different results (due to the order of evaluation). Therefore, the behavior is undefined.
sszd at 2007-11-9 0:57:52 >
