我们来看一道基础题q=(++j)+(++j)+(++j)
原题是这样的:
int main(int argc, char* argv[])
{
int i=5,j=5,p,q;
p=(i++)+(i++)+(i++);
q=(++j)+(++j)+(++j);
printf("%d,%d,%d,%d",p,q,i,j);
getchar();
return 0;
}
在VC6环境下DEBUG编译后显示结果15,22,8,8而Release编译后显示结果15,24,8,8而朋友在linux下cc -o test test.c后运行显示的结果也是15,22,8,8而VS.NET2005编译后debug和release的结果都是15,24,8,8,为什么会有这样的差异呢?p、i、j的值没有差异,我单独把q的运算反汇编结果分析了一下
.net下反汇编
int i=5,j=5,p,q;
0041342E mov dword ptr [i],5
00413435 mov dword ptr [j],5
q=(++j)+(++j)+(++j);
00413463 mov eax,dword ptr [j]
00413466 add eax,1 //++j
00413469 mov dword ptr [j],eax
0041346C mov ecx,dword ptr [j]
0041346F add ecx,1 //++j
00413472 mov dword ptr [j],ecx
00413475 mov edx,dword ptr [j]
00413478 add edx,1 //++j
0041347B mov dword ptr [j],edx
0041347E mov eax,dword ptr [j]
00413481 add eax,dword ptr [j] //8+8
00413484 add eax,dword ptr [j] //16+8=24
00413487 mov dword ptr [q],eax //q=24
VC6 DEBUG反汇编
8: int i=5,j=5,p,q;
0040D6F8 mov dword ptr [ebp-4],5
0040D6FF mov dword ptr [ebp-8],5
10: q=(++j)+(++j)+(++j);
0040D72D mov ecx,dword ptr [ebp-8]
0040D730 add ecx,1
0040D733 mov dword ptr [ebp-8],ecx
0040D736 mov edx,dword ptr [ebp-8]
0040D739 add edx,1
0040D73C mov dword ptr [ebp-8],edx
0040D73F mov eax,dword ptr [ebp-8]
0040D742 add eax,dword ptr [ebp-8]//这里没有++j而是先做了前两个操作数的和eax=14
0040D745 mov ecx,dword ptr [ebp-8]//这时候dword ptr [ebp-8]=7
0040D748 add ecx,1 //做了++j这时候ecx=8
0040D74B mov dword ptr [ebp-8],ecx//j=8了
0040D74E add eax,dword ptr [ebp-8]//又做了14+8
0040D751 mov dword ptr [ebp-10h],eax //结果是q=22
我们看到其中的差异发生在.net的代码都是++j三次做完之后统一对三个操作数做了两次+运算,这样3个数的和是24,而VC6的debug是做了两次++j之后做的前两个操作数的+运算,然后又做的++j,然后再做的第二次加法,不知道小弟解释的是否清楚。可是为什么会有这样的差异?请各位牛人帮忙解释一下。debug的编译器时候还靠得住?