注意:我們在這裏談論(推測)符合C++ 98的編譯器。這不是一個C++ 11的問題。C++數組zero-initialization:這是一個錯誤,還是這是正確的?
我們有一個奇怪的行爲在我們的編譯器之一,我們不知道這是否正常,如果這是一個編譯器錯誤:
// This struct has a default constructor
struct AAA
{
AAA() : value(0) {}
int value ;
} ;
// This struct has a member of type AAA and an array of int, both surrounded
// by ints
struct BBB
{
int m_a ;
AAA m_b ;
int m_c ;
int m_d[42] ;
} ;
當BBB被這樣初始化:
BBB bbb = {0} ;
我們預計BBB的所有POD成員(包括m_d,int的數組)都將被初始化,並且BBB的所有非POD成員都將被構建。
這適用於AIX的本地編譯器,在Linux/GCC-3.4上,在Windows/VisualC++上......但不在Solaris/SunStudio上,其中只有非數組成員是零初始化的。
我們做了一些研究,在C++ 98標準(文件草案),在這裏我們發現:
[12.6.1 - 2]
當集合(無論是類還是數組)都包含類類型的成員,並且由括號括起來的初始化程序列表(8.5.1)進行初始化,每個這樣的成員都被相應的賦值表達式複製初始化(見8.5)。 如果初始化程序列表中的初始化程序少於聚合的成員,則每個未明確初始化的成員都應默認初始化(8.5)。
然後:
[8.5 - 5]
要零初始化存儲爲類型T的對象是指:
- 如果T是一個標量類型(3.9 ),存儲設置爲轉換爲T的值0(零);
- 如果T是非聯合類類型,則每個非靜態數據成員和每個基類子對象的存儲都將被初始化;
- 如果T是聯合類型,則其第一個數據成員89的存儲空間被初始化;
- 如果T是一個數組類型,則每個元素的存儲都是零初始化的;
- 如果T是參考類型,則不執行初始化。
然後:
爲默認初始化類型T的對象是指:
- 如果T是一個非POD類型(第9節),對於缺省的構造T被調用(並且如果T沒有可訪問的默認構造函數,則初始化不合格);
- 如果T是一個數組類型,則每個元素都默認初始化;
- 否則,該對象的存儲器將被初始化爲零。
我看它的方式:SunStudio應該零初始化整型(BBB :: M_D)的陣列
奇怪的事情:如果我們要從AAA默認構造函數,那麼一切都在BBB是零初始化。
問題:當SunStudio未能初始化包含非POD的結構的整數的數組的數組時,它的行爲是否爲標準?或者這是一個編譯器錯誤?
好像對我的錯誤。如果你寫了'BBB bbb = {0,0,0,{0}};' –
這是Sun CC中的錯誤。你對標準的理解是正確的。 –
@JamesKanze:我真的不滿意評論,也沒有選擇他們作爲答案...不要猶豫,以作出完整的答案... :-) – paercebal