2014-10-17 76 views
3

我一直在看這個小片段:MSVC2013和新的數組括號初始化問題

#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新初始化但找不到任何理由MSVC的行爲。

我錯過了什麼嗎?這是一個已知的問題?


編輯:我附加從MSVC存儲器轉儲和生成的彙編代碼(64釋放

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) 
+0

你把數組轉儲到gdb等了嗎? – user657267 2014-10-17 08:46:06

+0

我在MSVC中做過,我附加了內存轉儲 – 2014-10-17 08:46:32

+0

您是否嘗試過沒有'0',即'new char [len + 1] {};'?我的意思是它應該仍然用零來消除所有的東西,但是看到它會很有趣。 – user657267 2014-10-17 08:54:30

回答

2

它是MS VC++編譯器的一個錯誤。根據C++標準(5.3.4新)

17創建類型T的對象的新表達初始化該對象如下:

- 如果省略了新初始化,對象是缺省初始化(8.5);如果沒有執行初始化,則該對象具有不確定的值。

- 否則,根據8.5的初始化規則對新初始化器進行解釋以進行直接初始化。

並進一步(8.5.1聚集體)

7如果有較少的初始化子句在列表以外還有在聚集構件,然後不明確初始化每個成員應當從它的初始化撐 - 或 - 等初始值設定項,或者,如果沒有括號或等於初始值設定項,則從空初始值設定項列表(8.5.4)開始。

和(8.5.4列表初始化)

- 否則,如果初始化列表沒有任何元素,對象是值初始化

,最後(8.5初始值設定)

8類型T的對象裝置

到值初始化...

- 如果T是一個數組類型,則每個元素是值初始化; - 否則,該對象是零初始化的。

所以數組的所有元素都應該初始化爲零。