Bug 14417

Summary: output streams and post-increment operator have incorrect output.
Product: gcc Reporter: Eric McVicker <eric.mcvicker>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: gcc-bugs
Priority: P2    
Version: 3.3.3   
Target Milestone: ---   
Host: i386-redhat-linux Target: i386-redhat-linux
Build: i386-redhat-linux Known to work:
Known to fail: Last reconfirmed:

Description Eric McVicker 2004-03-03 20:59:09 UTC
Utilizing the post increment operator within a stream operation does not result
in the expected output.  Output is reversed.  Based on the grammer of the
language, this should work as expected and not as currently implemented.

THe following program will replicate the problem:

#include <iostream>
#include <fstream>

using namespace std;


char *str = "0123456789ABCDEF";

int main(int argc, char **argv)
{
   char *ptr;

#if defined(COUT_TOO)
   ptr = str;

   cout << *ptr++ << *ptr++ << ' ';
   cout << *ptr++ << *ptr++ << ' ';
   cout << *ptr++ << *ptr++ << ' ';
   cout << *ptr++ << *ptr++ << ' ';
   cout << *ptr++ << *ptr++ << ' ';
   cout << *ptr++ << *ptr++ << ' ';
   cout << *ptr++ << *ptr++ << ' ';
   cout << *ptr++ << *ptr++ << ' ';
   cout << endl;
#endif

   ostream  *outStream;

   outStream = new ofstream("foo.txt");
   ptr = str;

   *outStream << *ptr++ << *ptr++ << ' ';
   *outStream << *ptr++ << *ptr++ << ' ';
   *outStream << *ptr++ << *ptr++ << ' ';
   *outStream << *ptr++ << *ptr++ << ' ';
   *outStream << *ptr++ << *ptr++ << ' ';
   *outStream << *ptr++ << *ptr++ << ' ';
   *outStream << *ptr++ << *ptr++ << ' ';
   *outStream << *ptr++ << *ptr++ << ' ';
   *outStream << endl;

   delete outStream;

   // Same concept, different syntax works.

#if defined(COUT_TOO)
   ptr = str;

   cout << *ptr++;
   cout << *ptr++ << ' ';
   cout << *ptr++;
   cout << *ptr++ << ' ';
   cout << *ptr++;
   cout << *ptr++ << ' ';
   cout << *ptr++;
   cout << *ptr++ << ' ';
   cout << *ptr++;
   cout << *ptr++ << ' ';
   cout << *ptr++;
   cout << *ptr++ << ' ';
   cout << *ptr++;
   cout << *ptr++ << ' ';
   cout << *ptr++;
   cout << *ptr++ << ' ';
   cout << endl;
#endif

   outStream = new ofstream("bar.txt");
   ptr = str;

   *outStream << *ptr++;
   *outStream << *ptr++ << ' ';
   *outStream << *ptr++;
   *outStream << *ptr++ << ' ';
   *outStream << *ptr++;
   *outStream << *ptr++ << ' ';
   *outStream << *ptr++;
   *outStream << *ptr++ << ' ';
   *outStream << *ptr++;
   *outStream << *ptr++ << ' ';
   *outStream << *ptr++;
   *outStream << *ptr++ << ' ';
   *outStream << *ptr++;
   *outStream << *ptr++ << ' ';
   *outStream << *ptr++;
   *outStream << *ptr++ << ' ';
   *outStream << endl;

}


The above program was compiled with the following command:

g++ -O0 -o foobar test.cxx -DCOUT_TOO


The output on the screen and found in the files is thus:

10 32 54 76 98 BA DC FE 
01 23 45 67 89 AB CD EF 

The specs of the compiler obtained with g++ -v is:

Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --disable-libunwind-exceptions --with-system-zlib
--enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.3.3 20040216 (Red Hat Linux 3.3.3-2)

I have even tried the latest snapshot of GCC 3.3.3 and it fails as well.  I also
compiled 3.3.1 and used it with the same results.
Comment 1 Wolfgang Bangerth 2004-03-03 21:15:52 UTC
No bug, please read the page on frequently reported bugs. operator<< 
is not a sequence point, so the question of when the pointer is  
increased and when it is dereferenced is undefined. 
 
W. 
Comment 2 Eric McVicker 2004-03-03 23:09:14 UTC
(In reply to comment #1)
> No bug, please read the page on frequently reported bugs. operator<< 
> is not a sequence point, so the question of when the pointer is  
> increased and when it is dereferenced is undefined. 
>  
> W. 

It's interesting that this has worked historically.  I see g++ 2.9.5 work 
appropriately on our Sun Solaris stations, as well as V3 work appropriately on 
our Macintosh systems.

I guess we'll resort to using something that actually works as most people 
would expect it to.
Comment 3 Wolfgang Bangerth 2004-03-03 23:23:34 UTC
The standard says that the behavior of your program is undefined in this 
case. Newer compilers are better at optimizing code, so they trip users 
writing undefined code more often. It's not the compiler's fault if it 
reorders code that the standard allows it to reorder. 
 
W. 
 
PS: To understand what's going on, read the entry on -Wsequence-point 
in the manual. 
Comment 4 Wolfgang Bangerth 2004-08-05 14:57:12 UTC
Reopen these bugs... 
Comment 5 Wolfgang Bangerth 2004-08-05 15:01:36 UTC
...mark as duplicate of PR 11751. 

*** This bug has been marked as a duplicate of 11751 ***