int main(){
int x = 0;
f() += 1;
f() = f() + 1;
cout << f();
}
What should be the output of the code shown?
VS gives 5 and gcc gives 6.
Regards,
Dabs.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
We don't know. In the third statement, the f's could be called in any
order. Either would be correct.
Bo Persson
> int& f(){
> static int x = 0;
> x++;
> return x;
> }
>
> int main(){
> int x = 0;
> f() += 1;
> f() = f() + 1;
>
> cout << f();
> }
>
> What should be the output of the code shown?
>
> VS gives 5 and gcc gives 6.
>
The output is unspecified, because the orderof value computation of the
operands of op= is unspecified. Lvalue computation of the two f()'s are
unsequenced. So how the "f()" value in "f() + 1" gets computed to can be
either
f() += 1; // after which f.x == 2
f() = f() + 1 // after which f.x == 5 or 4
cout << f() // after which f.x == 6 or 5
As per my opinion your code invokes Undefined Behaviour because the
order of evaluation of arguments of assignment operator is unspecified
and both right hand side and left hand side f() refer to the same
static variable. So indirectly you are trying to modify the variable
more than once between two sequence points.
Somebody please correct me if I am wrong.
> int& f(){
> static int x = 0;
> x++;
> return x;
> }
>
> int main(){
> int x = 0;
> f() += 1;
> f() = f() + 1;
>
> cout << f();
> }
>
> What should be the output of the code shown?
>
> VS gives 5 and gcc gives 6.
The output is undefined. The problem here is that "f() = f() + 1"
doesn't specify which f() will be resolved first and which second.
Both are correct. Everything is simple up to the expression that calls
f twice.
The order of evaluation around assignment isn't specified, so the
compiler could execute the lhs call, increasing x to 3 and yielding a
reference, then execute the rhs call, increasing x to 4, fetch x, add
1 and assign back to the reference to yield 5.
Or it could execute the rhs call, increasing x to 3 and yielding a
reference, then fetch the value there, add 1 to get 4, then execute
the lhs call, increasing x to 4, and assign the 4 for the previous
computation.
There are some other valid execution orders, but those two should be
enough to illustrate the issue.
Sebastian
{ quoted clc++m banner removed -mod }
Don't you think the terms 'sequenced' and 'unsequenced' should be used
in the context of C++0x?
Slightly. :-)
There are sequence points in the function calls, so the behavior is
not undefined. But, like you say, it is unspecified in which order the
functions are called. That makes more than one result possible, and we
don't know which one we get.
Bo Persson
Since you ask :-) The problem isn't in the assignment itself, but
in the x++. There is a specific exception for assignments, but the
x++ is a side-effect within one. Otherwise, you are correct.
Regards,
Nick Maclaren.
It looks like several posters have mixed-up "unspecified results" with
"undefined behavior".
The order of execution of two calls to f() is unspecified.
But your program invokes undefined behaviour (which is quite different)
because it tries to modify the same lvalue without a sequence point.
Andy.
Stefan,the order of evaluation is not 'undefined', it is 'unspecified'
rather, however, the behaviour of the program as a whole is
undefined. :)
There is a sequence point at each function call and return, and the
function invocations can't be interleaved, so I don't think x is modified
twice without an intervening sequence point.
-- Dave Harris, Nottingham, UK.
It depends on the compiler optimizations I think.
If you make them volatile, like change
int& f() {
static int x = 0;...
to
volatile int& f() {
static volatile int x = 0;..
I think the results would be more predictable. Have you tried using
volatile int instead?
Srinivasan
The described problem is unaffected by the semantics
of volatile. If that "works" in your case, it is nothing, you
can generally rely on.
HTH & Greetings from Bremen,
Daniel Krügler