[cprg]$ cat test.c
#include  <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
        int i=10;
        printf("i=%d\ni++=%d\n++i=%d\n",i,i++,++i);
        return 0;
}
[cprg]$ make
gcc -g -Wall -o test test.c
test.c: In function ‘main’:
test.c:7: warning: operation on ‘i’ may be undefined
test.c:7: warning: operation on ‘i’ may be undefined
[cprg]$ ./test
i=12
i++=11
++i=12
I have no idea why this thing is happening. Please can anyone explain me in detail as to what is happening here ?
C does not define in which order function call arguments get evaluated. You are in for trouble there ;).
Update:
To clarify what is defined and what not:
The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.
From ISO/IEC 9899:1999, Section 6.5.2.2, Function calls
Here's the disassembly of main (the part we need):
0x080483ed <+9>:    movl   $0xa,0x1c(%esp)         # initializes i
0x080483f5 <+17>:   addl   $0x1,0x1c(%esp)         # i += 1
0x080483fa <+22>:   mov    0x1c(%esp),%edx        # edx = i = 11
0x080483fe <+26>:   addl   $0x1,0x1c(%esp)         # i += 1
0x08048403 <+31>:   mov    $0x80484f0,%eax         # address of string
0x08048408 <+36>:   mov    0x1c(%esp),%ecx        # ecx = i = 12
0x0804840c <+40>:   mov    %ecx,0xc(%esp)         # pushes ecx (++i)
0x08048410 <+44>:   mov    %edx,0x8(%esp)         # and edx (i++)
0x08048414 <+48>:   mov    0x1c(%esp),%edx        # now gets edx (i)
0x08048418 <+52>:   mov    %edx,0x4(%esp)         # and pushes it
0x0804841c <+56>:   mov    %eax,(%esp)            # push address of string
0x0804841f <+59>:   call   0x804831c <printf@plt> # write
now, since arguments are pushed on the stack in reverse order, the disassembly shows that the first that is pushed is ecx, so we can assume it's ++i (since it's the last argument in printf), so edx is i++. Strangely, it decides to compute first i++, then ++i. At the end it loads i and pushes it, but, at this point, i has been increased two times, so it's 12. This is really undefined behavior! Look:
printf("++i=%d\ni++=%d\ni=%d\n",++i,i++,i);
produces:
++i=12
i++=10
i=12
Check this StackOverflow link for further information on argument evaluation order:
Compilers and argument order of evaluation in C++
It has to do with evaluation order of i, i++ and ++i expression on C. As an example is OK, but in real code do not rely on that order if you want to avoid weird issues.
 
         
                                         
                                         
                                         
                                        ![Interactive visualization of a graph in python [closed]](https://www.devze.com/res/2023/04-10/09/92d32fe8c0d22fb96bd6f6e8b7d1f457.gif) 
                                         
                                         
                                         
                                         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论