考虑以下两个无用的C ++函数。
使用GCC(4.9.2,32或64位)编译,两个函数都返回与预期相同的值。
使用Visual Studio 2010或Visual Studio 2017(非托管代码)编译,这两个函数都返回不同的值。
我尝试过的事情:
这里发生了什么? 这似乎是VS中的一个基本错误。
char test1()
{
char buf[] = "The quick brown fox...", *pbuf = buf;
char value = (*(pbuf++) & 0x0F) | (*(pbuf++) & 0xF0);
return value;
}
char test2()
{
char buf[] = "The quick brown fox...", *pbuf = buf;
char a = *(pbuf++) & 0x0F;
char b = *(pbuf++) & 0xF0;
char value = a | b;
return value;
}
修改
很抱歉给您带来不便,但这不是我所期待的。没有语言。
为了完整性,这里是test1()的反汇编代码:
0028102A mov ecx,dword ptr [ebp-8]
0028102D movsx edx,byte ptr [ecx]
00281030 and edx,0Fh
00281033 mov eax,dword ptr [ebp-8]
00281036 movsx ecx,byte ptr [eax]
00281039 and ecx,0F0h
0028103F or edx,ecx
00281041 mov byte ptr [ebp-1],dl
00281044 mov edx,dword ptr [ebp-8]
00281047 add edx,1
0028104A mov dword ptr [ebp-8],edx
0028104D mov eax,dword ptr [ebp-8]
00281050 add eax,1
00281053 mov dword ptr [ebp-8],eax
答案 0 :(得分:10)
(*(pbuf++) & 0x0F) | (*(pbuf++) & 0xF0);
的行为未定义。 |
(与||
不同)不一个排序点,因此您可以在同一程序步骤中同时对pbuf
进行读写操作。
因此不是VS的错误。 (这样的事情很少:黄金法则不应该责怪编译器。)
(另请注意char
可以是signed
或unsigned
。这可能会引入与您类似的代码差异。)