2013-08-19 72 views
14

注意:我們在這裏談論(推測)符合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的結構的整數的數組的數組時,它的行爲是否爲標準?或者這是一個編譯器錯誤?

+4

好像對我的錯誤。如果你寫了'BBB bbb = {0,0,0,{0}};' –

+10

這是Sun CC中的錯誤。你對標準的理解是正確的。 –

+0

@JamesKanze:我真的不滿意評論,也沒有選擇他們作爲答案...不要猶豫,以作出完整的答案... :-) – paercebal

回答

2

這的確是Sun/Solaris的一個bug。 你寫的東西確實是應該發生的事情,你對你寫的所有東西都是正確的。

1

這在Sun CC中顯然是錯誤的。標準很清楚,你對此的理解是正確的。

1

這似乎是一個錯誤 - 我沒有使用Solaris編譯器的經驗,但我曾經使用的所有其他編譯器將允許這種初始化。

我建議解決該問題通過更明確的:

BBB bbb = {0, 0, 0, {0} }; 
相關問題