Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

output?

3 views
Skip to first unread message

Anubhav

unread,
Aug 7, 2010, 6:18:04 AM8/7/10
to
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.

Regards,
Dabs.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Stefan van Kessel

unread,
Aug 7, 2010, 11:09:03 PM8/7/10
to
The code you posted relies upon the order of evaluation within the statement "f() = f() + 1;". Either the first or the second invocation of f() has to come first. If the first comes first, you have x = 4 + 1; (x is now 5) If the second comes first you have essentially ++x = 3 + 1. (x is now 4) Since I'm pretty sure the order of evaluation here is undefined, the behavior also is undefined. If you've got a copy of the standard at hand, look at 1.9.15.

Bo Persson

unread,
Aug 7, 2010, 11:06:21 PM8/7/10
to
Anubhav wrote:
> 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.
>
> Regards,
> Dabs.

We don't know. In the third statement, the f's could be called in any
order. Either would be correct.


Bo Persson

Johannes Schaub (litb)

unread,
Aug 7, 2010, 11:07:00 PM8/7/10
to
Anubhav wrote:

> 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

Prasoon Saurav

unread,
Aug 7, 2010, 11:32:39 PM8/7/10
to
On Aug 7, 3:18 pm, Anubhav <rkld...@gmail.com> wrote:
> 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.
>
> Regards,
> Dabs.
>

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.

Daniel T.

unread,
Aug 8, 2010, 5:42:03 PM8/8/10
to
Anubhav <rkl...@gmail.com> wrote:

> 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.

CornedBee

unread,
Aug 8, 2010, 5:45:23 PM8/8/10
to
On Aug 7, 3:18 am, Anubhav <rkld...@gmail.com> wrote:
> 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.

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

Prasoon Saurav

unread,
Aug 8, 2010, 5:52:24 PM8/8/10
to
On Aug 8, 8:07 am, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:

> Anubhav wrote:
> > 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

{ quoted clc++m banner removed -mod }


Don't you think the terms 'sequenced' and 'unsequenced' should be used
in the context of C++0x?

Bo Persson

unread,
Aug 9, 2010, 10:52:13 AM8/9/10
to
Prasoon Saurav wrote:
> On Aug 7, 3:18 pm, Anubhav <rkld...@gmail.com> wrote:
>> 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.
>>
>> Regards,
>> Dabs.
>>
>
> 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.

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

Nick Maclaren

unread,
Aug 9, 2010, 11:48:37 AM8/9/10
to
In article
<fce17895-95ff-4f2b...@i18g2000pro.googlegroups.com>,

Prasoon Saurav <prasoons...@gmail.com> wrote:
>On Aug 7, 3:18 pm, Anubhav <rkld...@gmail.com> wrote:
>> 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.
>>
>
>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.

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.

Andy Venikov

unread,
Aug 10, 2010, 12:17:07 AM8/10/10
to
Daniel T. wrote:
> Anubhav <rkl...@gmail.com> wrote:
>
>> 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.
>

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.

Prasoon Saurav

unread,
Aug 10, 2010, 4:58:56 AM8/10/10
to
>Since I'm pretty sure the order of evaluation here is undefined, the behavior also is undefined. If you've got a copy of the standard at hand, look at 1.9.15.

Stefan,the order of evaluation is not 'undefined', it is 'unspecified'
rather, however, the behaviour of the program as a whole is
undefined. :)

Dave Harris

unread,
Aug 10, 2010, 4:59:04 AM8/10/10
to
prasoons...@gmail.com (Prasoon Saurav) wrote (abridged):

> On Aug 7, 3:18 pm, Anubhav <rkld...@gmail.com> wrote:
> > int& f(){
> > static int x = 0;
> > x++;
> > return x;
> >
> > }
> >
> > int main(){
> > int x = 0;
> > f() += 1;
> > f() = f() + 1;
> >
> > cout << f();
> >
> > }
>
> 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.

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.

chini koni

unread,
Aug 12, 2010, 3:09:48 AM8/12/10
to
On Aug 7, 3:18 am, Anubhav <rkld...@gmail.com> wrote:
> 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.

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

Daniel Krügler

unread,
Aug 12, 2010, 2:16:30 PM8/12/10
to
On 12 Aug., 09:09, chini koni <chinik...@gmail.com> wrote:
> On Aug 7, 3:18 am, Anubhav <rkld...@gmail.com> wrote:
>
> > 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.
>
> 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?

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

0 new messages