output difference between VC and gcc

Bob Plantz plantz@cds1.net
Sat Jul 17 15:46:00 GMT 2010


On Sat, 2010-07-17 at 07:17 +0300, Mihai Donțu wrote:
> On Saturday 17 July 2010 06:48:35 Peter wrote:
> > Hi,
> > I have the following code compiled in both microsoft VC 2008 and gcc
> > version 4.1.2 20071124.
> > 
> > The output is different.
> > 
> > #include<stdio.h>
> > void main(void)
> > {
> >     int i,tab[]={1,2,3,4,5,6,7,8,9,10};
> > 
> >     i=0;
> >     while(i<10){
> >         printf("%d  ",i);
> >               
> >     }
> > }
> > 
> > [...]
> > 
> > based on C standard, whose output is correct?
> > thanks.
> 
> GCC's, although it's interesting that visual studio does what one expects: 
> print i, print tab[i], then increment i. However, keeping in mind that 
> parameters are pushed on stack in reverse:
> 
>   mov    0xfffffff4(%ebp),%eax
>   pushl  0xffffffb8(%ebp,%eax,4)
>   lea    0xfffffff4(%ebp),%eax
>   incl   (%eax)
>   pushl  0xfffffff4(%ebp)
>   push   $0x80484f1
>   call   80482b0 <_init+0x38>
> 
> things actually happen: print tab[i], print ( i + 1 ). Given the right 
> options, gcc can warn about this:
> 
> gcc -W -Wall test.c 
> ...
> test.c: In function `main':
> test.c:9: warning: operation on `i' may be undefined
> 
> Unfortunately, many programmers don't know these details and VS helps avoid 
> undesired results:
> 
>   mov     ecx, [ebp+var_4]
>   mov     edx, [ebp+ecx*4+var_2C]
>   mov     [ebp+var_30], edx
>   mov     eax, [ebp+var_30]
>   push    eax
>   mov     ecx, [ebp+var_4]
>   push    ecx
>   push    offset aDD
>   call    _printf
>   add     esp, 0Ch
>   mov     edx, [ebp+var_4]
>   add     edx, 1 ; <---- i++
>   mov     [ebp+var_4], edx
> 
> Thumb's up to VS. :-)
> 

I say thumbs down to the programmer who would write such code.

I'm a strong advocate of simple code. This example illustrates the
problem with trying to do "clever" things, like performing operations on
variables within an argument list. This sequence should be written
either:
     i++;
     printf("%d:%d\n",i,tab[i]);
or:
     printf("%d:%d\n",i,tab[i]);
     i++;
depending on what the programmer intends. Then the code is more easily
maintained and portable. Maintenance programmers (all of us at some
point in our careers) should not need to consult the code lawyers in
order to figure out how an algorithm behaves.

I have had co-workers justify their clever code on the basis of
efficiency. Programmer typing efficiency and code execution efficiency
are separate issues. Both usually take a distant back seat to
maintenance efficiency.

--Bob




More information about the Gcc-help mailing list