指针算术视觉工作室C

Pointer arithmetic Visual Studio C++

本文关键字:工作室 视觉 指针      更新时间:2023-10-16

考虑以下两个无用的C 功能。

用GCC编译(4.9.2,32-或64位(两个功能都返回与预期相同的值。

与Visual Studio 2010或Visual Studio 2017(非托管代码(一起编译的两个功能都返回不同的值。

我尝试了什么:

  • 支架,支架,支架
  • 明确的演员表
  • sizeof(char(被评估为1
  • 调试/发行版本
  • 32-/64-bit

这里发生了什么?这似乎是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;
}

编辑:

  • 这不是责备vs的尝试(如帖子中提到(。
  • 这不是签名或未签名的问题。
  • 这不是操作员左右评估顺序的问题。更改test2((中A和B分配的顺序会产生第三个结果。
  • 但同时性是一个好点。似乎评估的顺序被定义为未定义。在第一步中,生成的代码评估了test1((中的完整表达式,而无需增加任何指针。在第二步中,指针将被递增。由于增量没有效果,并且在此特定操作之后数据保持不变,因此优化器将删除代码。

对不起,对不起,但这不是我期望的。没有语言。

为了完整性,在这里拆卸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

因此不是与错误。(这样的事情很少是:黄金法则不应该责怪编译器。(

(还请注意char可以是signedunsigned。可以引入像您一样的代码差异。(