Today, my friend Yuan Yuan showed me a piece of C code, which gives different result under different optimization option. I was greatly surprised that such code exists. His original code is complicated. I minimized the code in order to demonstrate the problem.

1
2
3
4
5
int main() { 
int i=0;
int a[2]={0};
a[i]=++i;
}
1
2
3
4
5
int i=0;
int main() {
int a[2]={0};
a[i]=++i;
}

This two piece of code will give different result on windows 7 Professional, compiled using MingW’s g++ 4.50. More specifically, in the first program, _a_ finally becomes [0,1], while in second one, it is [1,0]. Let’s look at the assembly code generated by compiler:

1
2
3
4
5
6
7
8
9
10
11
incl	12(%esp)		# i++;
movl 12(%esp), %eax
movl 12(%esp), %edx
movl %edx, 4(%esp,%eax,4) # a\[i\]=i;

movl _i, %eax # int temp=i;
movl _i, %edx
incl %edx
movl %edx, _i # i++;
movl _i, %edx
movl %edx, 8(%esp,%eax,4) # a\[temp\]=i;

Comment is equivalent C code. We can see that they are doing completely different things. I am not sure which one is correct behavior of ++ operator, or even the behavior of ++ operator is undefined in this case.

The lesson is: never write code like a[i]=i++.