【问题标题】:Is this a microsoft VC++ 2010 compiler bug of "new auto(enum_type)"这是“new auto(enum_type)”的 microsoft VC++ 2010 编译器错误吗
【发布时间】:2012-06-29 11:04:03
【问题描述】:

环境:Microsoft Visual Studio 2010 SP1 Preminum(10.0.40219.1 SP1Rel),Windows XP SP3

VC10 编译器支持 auto 关键字,但推断的类型相关信息似乎并不总是正确的枚举。

示例:

#include <type_traits>

enum fruit_t
{
    apple = 100,
    banana = 200,
};

int main()
{
    const auto pa = new auto(banana);
    const auto pb = new fruit_t(banana);
    static_assert(std::is_same<decltype(pa), decltype(pb)>::value, "not same!");
    delete pb;
    delete pa;
}

上面的代码应该没有编译时错误或运行时错误。但令我惊讶的是,它编译正常,没有任何错误或警告,但运行不正确。退出主函数后调试器告诉:

检测到堆损坏:在 0x00034878 的 %hs 块 (#55) 之后。 CRT 检测到应用程序在堆缓冲区结束后写入内存。

所以我猜编译器可能在“自动”类型推导中存在错误。下面的汇编器窗口显示,第一个“operator new”调用中请求的内存大小为 1 个字节,而第二个“operator new”调用为 4 个字节。这表明编译器在推导类型的大小上犯了很大的错误。

您认为这是编译器错误吗? Microsoft 是否有任何错误修复?

int main()
{
004113C0  push        ebp  
004113C1  mov         ebp,esp  
004113C3  sub         esp,10Ch  
004113C9  push        ebx  
004113CA  push        esi  
004113CB  push        edi  
004113CC  lea         edi,[ebp-10Ch]  
004113D2  mov         ecx,43h  
004113D7  mov         eax,0CCCCCCCCh  
004113DC  rep stos    dword ptr es:[edi]  
    const auto pa = new auto(banana);
004113DE  push        1  
004113E0  call        operator new (411181h)  
004113E5  add         esp,4  
004113E8  mov         dword ptr [ebp-104h],eax  
004113EE  cmp         dword ptr [ebp-104h],0  
004113F5  je          main+51h (411411h)  
004113F7  mov         eax,dword ptr [ebp-104h]  
004113FD  mov         dword ptr [eax],0C8h  
00411403  mov         ecx,dword ptr [ebp-104h]  
00411409  mov         dword ptr [ebp-10Ch],ecx  
0041140F  jmp         main+5Bh (41141Bh)  
00411411  mov         dword ptr [ebp-10Ch],0  
0041141B  mov         edx,dword ptr [ebp-10Ch]  
00411421  mov         dword ptr [pa],edx  
    const auto pb = new fruit_t(banana);
00411424  push        4  
00411426  call        operator new (411181h)  
0041142B  add         esp,4  
0041142E  mov         dword ptr [ebp-0F8h],eax  
00411434  cmp         dword ptr [ebp-0F8h],0  
0041143B  je          main+97h (411457h)  
0041143D  mov         eax,dword ptr [ebp-0F8h]  
00411443  mov         dword ptr [eax],0C8h  
00411449  mov         ecx,dword ptr [ebp-0F8h]  
0041144F  mov         dword ptr [ebp-10Ch],ecx  
00411455  jmp         main+0A1h (411461h)  
00411457  mov         dword ptr [ebp-10Ch],0  
00411461  mov         edx,dword ptr [ebp-10Ch]  
00411467  mov         dword ptr [pb],edx  
    static_assert(std::is_same<decltype(pa), decltype(pb)>::value, "not same!");
    delete pb;
0041146A  mov         eax,dword ptr [pb]  
0041146D  mov         dword ptr [ebp-0ECh],eax  
00411473  mov         ecx,dword ptr [ebp-0ECh]  
00411479  push        ecx  
0041147A  call        operator delete (411087h)  
0041147F  add         esp,4  
    delete pa;
00411482  mov         eax,dword ptr [pa]  
00411485  mov         dword ptr [ebp-0E0h],eax  
0041148B  mov         ecx,dword ptr [ebp-0E0h]  
00411491  push        ecx  
00411492  call        operator delete (411087h)  
00411497  add         esp,4  
}

【问题讨论】:

  • 在调试器中pa的类型是什么?
  • 调试器显示:banana 0x000000c8 int; pa 0x000329d8fruit_t * 常量; pb 0x00032a18fruit_t * 常量。糟糕的是,它表明 'banana' 是 'int' 类型(不是 'fruit_t')。据我所知,VC10的调试器有很多bug,所以上面显示的类型信息很可疑。
  • 尽管我的调试器 VS2010 显示了正确的类型 (fruit*),但它在自动分配的那些上崩溃。
  • 我的猜测是 auto 在该语法中不起作用(您正在尝试创建一个可以是 int 或 fruit 的香蕉类型 auto),因为表达式 auto x = auto(banana); 将显示。你可以做的是decltype(banana)(banana),但这并不漂亮。
  • C++11 标准有示例代码auto x = new auto(’a’);,第 5.3.4 节第 2 节。所以我认为它也可以在枚举中使用。

标签: c++ visual-c++ enums c++11 auto


【解决方案1】:

是的,我认为这是 VS2010 的错误。使用 XP SP3(32 位)和 VS2010 SP1 与您运行相同(或至少非常相似),我得到完全相同的错误。它看起来是特定于枚举的,因为在类中尝试它表明一切正常。我还尝试在枚举中添加另一个水果项,其值为 100000,以确保它不像您的枚举那样愚蠢,所有值都低于 255。结果相同。

我在Microsoft Connect 进行了快速搜索,但我没有看到关于此的错误报告,所以我建议您输入一个。这是确保 Microsoft 知道并可能修复它的最佳方式。

【讨论】:

  • 这个bug在VS2012中已经修复了,提交反馈报告没有意义。
  • 我认为仍应提交反馈报告。首先,VS2012 还没有发布。更重要的是,即使(何时)它被关闭为“不会修复”,至少它会在那里供其他人找到。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多