2013-03-26 71 views
6

我在gcc下使用默認C語言。C使用現有的常量變量初始化const結構成員

我的代碼:

typedef struct _OpcodeEntry OpcodeEntry; 

//

struct _OpcodeEntry 
{ 
    unsigned char uOpcode; 
    OpcodeMetadata pMetadata; 
}; 

//

const OpcodeMetadata omCopyBytes1 = { 1, 1, 0, 0, 0, 0, &CopyBytes }; 

const OpcodeEntry pOpcodeTable[] = 
{ 
    { 0x0, omCopyBytes1 }, 
}; 

錯誤:

error: initializer element is not constant 
error: (near initialization for 'pOpcodeTable[0].pMetadata') 

如果我將omCopyBytes1更改爲上述行中實際設置的值,代碼編譯得很好。我究竟做錯了什麼?

回答

5

不能使用omCopyBytes1初始化pOpcodeTable[]陣列中的一員,因爲omCopyBytes1是運行時間常數,不是編譯時間常數的變量。 C中的聚合初始化器必須是編譯時常量,這就是爲什麼你的文章中的代碼不能編譯的原因。

作爲一個變量,omCopyBytes1在內存中有自己的位置,它被初始化爲一組項目。您可以通過指針使用這些變量,像這樣:

struct _OpcodeEntry { 
    unsigned char uOpcode; 
    const OpcodeMetadata *pMetadata; 
}; 
... 
const OpcodeEntry pOpcodeTable[] = { 
    { 0x0, &omCopyBytes1 }, // This should work 
}; 

或者,你可以把它的預處理器常數:

#define omCopyBytes1 { 1, 1, 0, 0, 0, 0, &CopyBytes } 

如果以這種方式定義的,omCopyBytes1將不再是一個變量:這將是一個預處理器定義,在編譯器完成之前消失。我會建議不要使用預處理器方法,但如果你必須這樣做,它就在那裏。

+0

是否需要使用常量表達式來初始化C99中的所有聚合?在C99標準的6.7.8節中我沒有看到這樣的內容(靜態存儲持續時間的對象除外)。 – jamesdlin 2013-03-26 10:35:02

0

在C中,靜態存儲持續時間對象的初始值設定項必須爲常量表達式。 A const限定變量不是常量表達式。

+0

當然,你並不是說所有的*初始化符都必須是常量表達式,除非你聲稱'int x = rand();'是非法的。 – jamesdlin 2013-03-26 10:41:30

+0

謝謝..修正。 – 2013-03-26 13:29:57