Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #10999 > unrolled thread

Help with post-increment and sequence points

Started bylaird@lbreyer.com
First post2011-10-20 00:23 -0700
Last post2011-10-20 18:09 +0200
Articles 8 — 6 participants

Back to article view | Back to comp.lang.c++


Contents

  Help with post-increment and sequence points laird@lbreyer.com - 2011-10-20 00:23 -0700
    Re: Help with post-increment and sequence points Leigh Johnston <leigh@i42.co.uk> - 2011-10-20 12:57 +0100
    Re: Help with post-increment and sequence points softwareEngineer <ovNOSPAM@NOSPAMlibero.it> - 2011-10-20 14:16 +0200
    Re: Help with post-increment and sequence points Victor Bazarov <v.bazarov@comcast.invalid> - 2011-10-20 08:26 -0400
      Re: Help with post-increment and sequence points Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-10-20 06:06 -0700
        Re: Help with post-increment and sequence points Victor Bazarov <v.bazarov@comcast.invalid> - 2011-10-20 09:50 -0400
      Re: Help with post-increment and sequence points laird@lbreyer.com - 2011-10-20 14:16 -0700
    Re: Help with post-increment and sequence points Markus Wichmann <nullplan@gmx.net> - 2011-10-20 18:09 +0200

#10999 — Help with post-increment and sequence points

Fromlaird@lbreyer.com
Date2011-10-20 00:23 -0700
SubjectHelp with post-increment and sequence points
Message-ID<26287949.549.1319095405219.JavaMail.geo-discussion-forums@prfp13>
#include <iostream>
int main() {
  int i = 1;
  std::cout << i << i++ << i << "\n";
}

Compiling this code in g++ prints out 212 . Is this correct? If so, I don't understand why. 

Shouldn't this actually be equivalent to f(f(f(f(std::cout,i),i++),i),"\n") where f is operator<< ? In that case, each time a function is entered, there should be a sequence point which makes the side effects happen. So I'd expect the output to be 112 instead. 

% g++ --version
g++ (Debian 4.6.1-4) 4.6.1

Best regards,
Laird Breyer

[toc] | [next] | [standalone]


#11002

FromLeigh Johnston <leigh@i42.co.uk>
Date2011-10-20 12:57 +0100
Message-ID<TLydnXzHTIE9kT3TnZ2dnUVZ8qCdnZ2d@giganews.com>
In reply to#10999
On 20/10/2011 08:23, laird@lbreyer.com wrote:
> #include<iostream>
> int main() {
>    int i = 1;
>    std::cout<<  i<<  i++<<  i<<  "\n";
> }
>
> Compiling this code in g++ prints out 212 . Is this correct? If so, I don't understand why.
>
> Shouldn't this actually be equivalent to f(f(f(f(std::cout,i),i++),i),"\n") where f is operator<<  ? In that case, each time a function is entered, there should be a sequence point which makes the side effects happen. So I'd expect the output to be 112 instead.
>
> % g++ --version
> g++ (Debian 4.6.1-4) 4.6.1
>
> Best regards,
> Laird Breyer

There is a sequence point between evaluating all the function arguments 
and the call of the first function with no additional intervening 
sequence point so you are invoking undefined behaviour.

/Leigh

[toc] | [prev] | [next] | [standalone]


#11003

FromsoftwareEngineer <ovNOSPAM@NOSPAMlibero.it>
Date2011-10-20 14:16 +0200
Message-ID<j7p39s$fve$1@tdi.cu.mi.it>
In reply to#10999
Don't do that ....

http://www2.research.att.com/~bs/bs_faq2.html#evaluation-order 
<http://www2.research.att.com/%7Ebs/bs_faq2.html#evaluation-order>

bye.


Il 20/10/2011 09:23, laird@lbreyer.com ha scritto:
> #include<iostream>
> int main() {
>    int i = 1;
>    std::cout<<  i<<  i++<<  i<<  "\n";
> }
>
> Compiling this code in g++ prints out 212 . Is this correct? If so, I don't understand why.
>
> Shouldn't this actually be equivalent to f(f(f(f(std::cout,i),i++),i),"\n") where f is operator<<  ? In that case, each time a function is entered, there should be a sequence point which makes the side effects happen. So I'd expect the output to be 112 instead.
>
> % g++ --version
> g++ (Debian 4.6.1-4) 4.6.1
>
> Best regards,
> Laird Breyer

[toc] | [prev] | [next] | [standalone]


#11006

FromVictor Bazarov <v.bazarov@comcast.invalid>
Date2011-10-20 08:26 -0400
Message-ID<j7p41q$lt3$1@dont-email.me>
In reply to#10999
On 10/20/2011 3:23 AM, laird@lbreyer.com wrote:
> #include<iostream>
> int main() {
>    int i = 1;
>    std::cout<<  i<<  i++<<  i<<  "\n";

This expression actually means
     std::cout.
       operator<<(i).          // #1
         operator<<(i++).      // #2
           operator<<(i).      // #3
             operator<<("\n"); // #4

Which, in reality means

     mem_op<<(        // #4
       mem_op<<(      // #3
         mem_op<<(    // #2
           mem_op<< ( std::cout, i),  // #1
           i++ ), i ), "\n");

which, according to the Standard can have any order of evaluation of its 
operands, except that there is a sequence point before a call to a 
function.  So, before calling #4, it has to evaluate #3, which means it 
will call the function, and in order to do that it has to call #2, and 
in order to do that it has to call #1.  BUT...  The second operands in 
all those calls can be evaluated an *any* time after the expression 
starts evaluating just before the function call that needs it.  IOW, the 
*second* arguments could be evaluated as i,"\n",i,i++, and you would see 
111, which should still be "correct".  Or the order could be 
"\n",i++,i,i, which *could* give 211, or 222, depending on when the 
effects of ++ take place (they are supposed to take place before the 
next "intervening" sequence point).

> }
>
> Compiling this code in g++ prints out 212 . Is this correct? If so, I don't understand why.

It is just as correct as any other combination of 1s and 2s.

>
> Shouldn't this actually be equivalent to
f(f(f(f(std::cout,i),i++),i),"\n") where f is operator<< ? In that case,
each time a function is entered, there should be a sequence point which
makes the side effects happen. So I'd expect the output to be 112 instead.

Yes, but the sequence point has no effect on when the *second* argument 
for every call is evaluated.  You seem to forget that.

>
> % g++ --version
> g++ (Debian 4.6.1-4) 4.6.1
>
> Best regards,
> Laird Breyer

V
-- 
I do not respond to top-posted replies, please don't ask

[toc] | [prev] | [next] | [standalone]


#11008

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2011-10-20 06:06 -0700
Message-ID<e90405d2-6e18-4878-999b-25ceb923e097@fk25g2000vbb.googlegroups.com>
In reply to#11006
On Oct 20, 1:26 pm, Victor Bazarov <v.baza...@comcast.invalid> wrote:
> On 10/20/2011 3:23 AM, la...@lbreyer.com wrote:
>
> > #include<iostream>
> > int main() {
> >    int i = 1;
> >    std::cout<<  i<<  i++<<  i<<  "\n";
>
> This expression actually means
>      std::cout.
>        operator<<(i).          // #1
>          operator<<(i++).      // #2
>            operator<<(i).      // #3
>              operator<<("\n"); // #4
>
> Which, in reality means
>
>      mem_op<<(        // #4
>        mem_op<<(      // #3
>          mem_op<<(    // #2
>            mem_op<< ( std::cout, i),  // #1
>            i++ ), i ), "\n");
>
> which, according to the Standard can have any order of evaluation of its
> operands, except that there is a sequence point before a call to a
> function.  So, before calling #4, it has to evaluate #3, which means it
> will call the function, and in order to do that it has to call #2, and
> in order to do that it has to call #1.  BUT...  The second operands in
> all those calls can be evaluated an *any* time after the expression
> starts evaluating just before the function call that needs it.  IOW, the
> *second* arguments could be evaluated as i,"\n",i,i++, and you would see
> 111, which should still be "correct".  Or the order could be
> "\n",i++,i,i, which *could* give 211, or 222, depending on when the
> effects of ++ take place (they are supposed to take place before the
> next "intervening" sequence point).
>
> > }
>
> > Compiling this code in g++ prints out 212 . Is this correct? If so, I don't understand why.
>
> It is just as correct as any other combination of 1s and 2s.
>
>
>
> > Shouldn't this actually be equivalent to
>
> f(f(f(f(std::cout,i),i++),i),"\n") where f is operator<< ? In that case,
> each time a function is entered, there should be a sequence point which
> makes the side effects happen. So I'd expect the output to be 112 instead.
>
> Yes, but the sequence point has no effect on when the *second* argument
> for every call is evaluated.  You seem to forget that.

with both i and i++ in there is taht undefined behaviour- or merely
implementaion defined behaviour?

[toc] | [prev] | [next] | [standalone]


#11009

FromVictor Bazarov <v.bazarov@comcast.invalid>
Date2011-10-20 09:50 -0400
Message-ID<j7p8uo$mrq$1@dont-email.me>
In reply to#11008
On 10/20/2011 9:06 AM, Nick Keighley wrote:
> On Oct 20, 1:26 pm, Victor Bazarov<v.baza...@comcast.invalid>  wrote:
>> On 10/20/2011 3:23 AM, la...@lbreyer.com wrote:
>>
>>> #include<iostream>
>>> int main() {
>>>     int i = 1;
>>>     std::cout<<    i<<    i++<<    i<<    "\n";
>>
>> This expression actually means
>>       std::cout.
>>         operator<<(i).          // #1
>>           operator<<(i++).      // #2
>>             operator<<(i).      // #3
>>               operator<<("\n"); // #4
>>
>> Which, in reality means
>>
>>       mem_op<<(        // #4
>>         mem_op<<(      // #3
>>           mem_op<<(    // #2
>>             mem_op<<  ( std::cout, i),  // #1
>>             i++ ), i ), "\n");
>>
>> which, according to the Standard can have any order of evaluation of its
>> operands, except that there is a sequence point before a call to a
>> function.  So, before calling #4, it has to evaluate #3, which means it
>> will call the function, and in order to do that it has to call #2, and
>> in order to do that it has to call #1.  BUT...  The second operands in
>> all those calls can be evaluated an *any* time after the expression
>> starts evaluating just before the function call that needs it.  IOW, the
>> *second* arguments could be evaluated as i,"\n",i,i++, and you would see
>> 111, which should still be "correct".  Or the order could be
>> "\n",i++,i,i, which *could* give 211, or 222, depending on when the
>> effects of ++ take place (they are supposed to take place before the
>> next "intervening" sequence point).
>>
>>> }
>>
>>> Compiling this code in g++ prints out 212 . Is this correct? If so, I don't understand why.
>>
>> It is just as correct as any other combination of 1s and 2s.
>>
>>
>>
>>> Shouldn't this actually be equivalent to
>>
>> f(f(f(f(std::cout,i),i++),i),"\n") where f is operator<<  ? In that case,
>> each time a function is entered, there should be a sequence point which
>> makes the side effects happen. So I'd expect the output to be 112 instead.
>>
>> Yes, but the sequence point has no effect on when the *second* argument
>> for every call is evaluated.  You seem to forget that.
>
> with both i and i++ in there is taht undefined behaviour- or merely
> implementaion defined behaviour?

Well, since no requirement is set on the order in which the calls and 
the evaluation of the "second arguments" is going to happen, it is 
probably undefined.  The "implementation-defined" carries the 
requirement to be documented ([defns.impl.defined]), and the order of 
evaluating of the arguments does not have to be documented.

V
-- 
I do not respond to top-posted replies, please don't ask

[toc] | [prev] | [next] | [standalone]


#11030

Fromlaird@lbreyer.com
Date2011-10-20 14:16 -0700
Message-ID<16331545.1098.1319145393057.JavaMail.geo-discussion-forums@prfp13>
In reply to#11006
On Thursday, 20 October 2011 23:26:33 UTC+11, Victor Bazarov  wrote:
> >
> > Shouldn't this actually be equivalent to
> f(f(f(f(std::cout,i),i++),i),"\n") where f is operator<< ? In that case,
> each time a function is entered, there should be a sequence point which
> makes the side effects happen. So I'd expect the output to be 112 instead.
> 
> Yes, but the sequence point has no effect on when the *second* argument 
> for every call is evaluated.  You seem to forget that.

Victor, this explains why I was confused. I was secretly thinking of the other case

cout << "good " << "news " << "everybody\n";

where the compiler can also evaluate the strings in any order, but this works in that case because they are all constant, so every possible ordering gives the same return value. 

Thanks to everybody who responded.

[toc] | [prev] | [next] | [standalone]


#11023

FromMarkus Wichmann <nullplan@gmx.net>
Date2011-10-20 18:09 +0200
Message-ID<9nt5n8-4u1.ln1@voyager.wichi.de.vu>
In reply to#10999
On 20.10.2011 09:23, laird@lbreyer.com wrote:
> #include <iostream>
> int main() {
>   int i = 1;
>   std::cout << i << i++ << i << "\n";
> }
> 
> Compiling this code in g++ prints out 212 . Is this correct? If so, I don't understand why. 
> 
> Shouldn't this actually be equivalent to 
> f(f(f(f(std::cout,i),i++),i),"\n") where f is operator<< ?
> In that case, each time a function is entered, there should
> be a sequence point which makes the side effects happen. So
> I'd expect the output to be 112 instead.

This logic does not hold. You do call

f(f(std::cout, i), i++)

among other functions. However, the order in which the arguments to the
outer function are evaluated is unspecified. Thus you invoke undefined
behaviour. Which means the output could have been "undefined behaviour
detected!" or, indeed, anything.

> % g++ --version
> g++ (Debian 4.6.1-4) 4.6.1
> 
> Best regards,
> Laird Breyer

HTH,
Markus

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web