2011-06-06 184 views
16

我目前正在使用遺傳C++代碼,成功編譯與gcc 2.9.X.
我被要求將這個遺留代碼移植到gcc 3.4.X.大部分錯誤很容易糾正,但這個特別的錯誤讓我感到困惑。初始化C-struct的雙花括號的含義是什麼?

上下文:

struct TMessage 
    { 
    THeader header; 
    TData data; 
    }; 

struct THeader 
    { 
    TEnum myEnum; 
    TBool validity; 
    }; 

做了什麼:

const TMessage init = {{0}}; 

/* Later in the code ... */ 
TMessage message = init; 

我的問題(一個或多個)
什麼是{{}}運營商的意義?它是否將第一個字段(標頭)初始化爲二進制0?它是否將第一個結構的第一個字段(枚舉)初始化爲(文字)0?

我得到的3.4.6錯誤是invalid conversion from 'int' to 'TEnum',帶有一對或兩對花括號。

如何在不使用memset的情況下將我的結構設置爲一堆0?

在此先感謝。

+0

爲什麼要將代碼從舊版本的gcc移植到另一箇舊版本的gcc? – 2011-06-06 11:15:32

+0

在另一個平臺上編譯/鏈接/執行它。 – 2011-06-06 11:17:39

+0

不知道C++。在C中沒有錯誤(也許你的編譯器對錯誤點有幫助) – pmg 2011-06-06 11:19:46

回答

18

它初始化了POD結構的所有字段爲0。

理由:

const SomeStruct init = {Value}; 

初始化SomeStruct到價值,該結構至零的其餘部分的第一個字段(I忘記在節標準,但它的存在的地方)

這樣:

const SomeOtherStruct init = {{Value}}; 

初始化結構的第一個字段的第一個字段(結構的第一個字段本身是一個POD結構體)爲Value,其餘的第一個字段爲零,結構的其餘部分爲0.

此外,這不僅是工作,因爲C++禁止的int隱式轉換爲枚舉類型,所以你可以這樣做:

const SomeOtherStruct init = {{TEnum(0)}}; 
+1

所以你說'const TMessage init = {{myEnumFirstValue}};'會初始化我的枚舉,然後每隔一個字段爲0?它編譯成功,我現在關心運行時。不管怎麼說,還是要謝謝你 ! – 2011-06-06 11:20:50

+3

該標準的相關部分是8.5.1.7:*如果列表中的初始化程序少於聚合中的成員,則未明確初始化的每個成員應進行數值初始化* – 2011-06-06 11:21:54

+0

最後一部分是什麼意思? _應該被value-initialized_:通過編譯器? – 2011-06-06 11:24:16

1

你可以把它看作一個多維數組(如果有幫助的話)。然後,您使用該命令將兩個維度重置爲0。這工作,因爲(我認爲)結構中的值可以取0作爲一個值。

+0

謝謝!但是我錯過了每個**其他**字段初始化爲0的事實。 – 2011-06-06 11:21:54

3
  • 第一個括號是struct TMessage
  • 第二個支柱是struct THeader
  • 零字面是TEnum myEnum

在這種情況下,你與int0,這是incompatible conversion初始化TEnum

所以必須添加鑄造這樣的:

const TMessage init = {{TEnum(0)}}; 

在C/C++,如果partially initialized結構或陣列(僅一些所述第一字段/元素的),其餘將由default constructor初始化(對原始類型是零初始化)。 如果沒有默認構造函數或構造函數聲明爲private,則會發生編譯錯誤。

+1

其餘的將始終初始化爲零是不正確的。正如我在@ Autopulated的回答中發表的評論中所說的,它們將被*值初始化*。例如,如果其中一個成員是具有默認構造函數的類類型,那麼該構造函數將被調用。 – 2011-06-06 11:27:58

+0

@ Space_C0wb0y:我站好了。我編輯了我的答案 – dragon135 2011-06-06 14:52:58