指针运算Visual Studio C++

Pointer arithmetic Visual Studio C++

考虑以下两个无用的 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  

(*(pbuf++) & 0x0F) | (*(pbuf++) & 0xF0); 的行为是未定义|(与 || 不同) 不是 排序点,因此您可以在同一程序步骤中同时读取和写入 pbuf

因此不是 VS 错误。 (这样的事情很少见:黄金法则是不要责怪编译器。)

(另请注意,char 可以是 signedunsigned。这会像您的代码一样引入差异。)