MSVC2013和新阵列大括号初始化问题

时间:2014-10-17 08:34:25

标签: c++ visual-studio-2013

我一直在看这个小片段:

#include <iostream>
#include <cstring>

int main()
{
    char const *a = "my string";
    size_t len = strlen(a);
    char *b = new char[len + 1]{0};

    char *zeroes = new char[strlen(a) + 1];
    memset(zeroes, 0, strlen(a) + 1);

    std::cout << memcmp(b, zeroes, strlen(a) + 1); // 0 expected
}

gccclang正确输出0,但MSVC2013更新3输出1

我看过关于5.3.4/17 new-initializer new,但找不到任何证明MSVC行为的理由。

我错过了什么吗?这是一个已知的问题吗?


编辑:我从MSVC附加内存转储和生成的汇编代码( x64 release

enter image description here

int main()
{
000007F676571270  push        rbx  
000007F676571272  sub         rsp,20h  
    char const *a = "my string";
    size_t len = strlen(a);
    char *b = new char[len + 1]{0};
000007F676571276  mov         ecx,0Ah  
000007F67657127B  call        operator new[] (07F676571704h)  
000007F676571280  mov         rbx,rax  
000007F676571283  test        rax,rax  
000007F676571286  je          main+1Dh (07F67657128Dh)  
000007F676571288  mov         byte ptr [rax],0  // zero the first one out
000007F67657128B  jmp         main+1Fh (07F67657128Fh)  
000007F67657128D  xor         ebx,ebx  

    char *zeroes = new char[strlen(a) + 1];
000007F67657128F  mov         ecx,0Ah  
000007F676571294  call        operator new[] (07F676571704h)  

1 个答案:

答案 0 :(得分:2)

这是MS VC ++编译器的错误。根据C ++标准(5.3.4新)

17创建类型为T的对象的new-expression初始化该对象,如下所示:

- 如果省略new-initializer,则默认初始化对象(8.5);如果没有执行初始化,则该对象具有不确定的值。

- 否则,根据8.5的初始化规则解释new-initializer以进行直接初始化。

进一步(8.5.1聚合)

7如果列表中的初始化子条款少于聚合中的成员,则未明确初始化的每个成员应从其大括号或等号初始化器初始化,或者如果没有大括号 - 或 - equalinitializer,来自空的初始化列表(8.5.4)。

和(8.5.4列表初始化)

- 否则,如果初始化列表没有元素,则该对象是值初始化的

最后(8.5个初始化者)

8对T类型的对象进行值初始化意味着

...

- 如果T是数组类型,则每个元素都是值初始化的; - 否则,对象被零初始化。

因此,数组的所有元素都应为零初始化。