2015-05-21 40 views
-1

我想從通過變量遞交的常量值初始化結構中的字段。從變量初始化結構中的字段

typedef struct _A{ 
    uint a; 
}A; 
const A a = {9} ; const A b = { .a = 10 }; const A c = {0}; 

typedef struct _Z{ 
    A a; 
    A b; 
    A c; 
}Z; 
Z z = { a,b,c }; 

但這產生了編譯器錯誤:initializer element is not constant 因爲A,B和C被聲明爲const的不應該是在運行時修改了什麼不是很明顯。

什麼,我想在內存中,得到的是這樣的:

0x00 9 
0x04 10 
0x08 0 

因爲結構僅僅是一個整數數組。

現在的問題是如何可以告訴編譯器(使用臂-NONE-EABI-GCC),該變量abc用於像定義並可以/應當通過它們的內容,因爲只有一個參考來代替到z將出現在正在運行的程序中?
也許一些編譯指示或甚至預處理指令?

我正在構建A在我初始化的同一個宏a。看起來像這樣,但更復雜一些。

#define bar(name, ...)\ 
typedef struct __bar_##name{\ 
    List(applydef, __VA_ARGS__)\ 
}bar_##name;\ 
const bar_##name name ={List(applyset, __VA_ARGS__)}; 
bar(foobar, a,b) 

上述代碼是自我膨脹由於過度使用的定義。 我會在這裏接受的另一個解決方案是不生成新的結構,而是一個新的定義,我可以像這樣扔進宏。

+1

它是C還是C++?這不一樣。 –

+1

請選擇一種語言。 '{.a = 10}'不是標準的C++。 –

+0

這是不可能在c + +? – Zirafinu

回答

0

不幸的是,初始化程序{a,b,c}不是常量,但是您的聲明z要求它是。

[C99: 6.6/7]:對於初始值設定項中的常量表達式,允許更多的緯度。這樣的常量表達式應,或評估於下列中的一種:

  • 算術常量表達式,
  • 空指針常量,
  • 一個地址常量,或
  • 一個地址常量一個對象類型加上或減去一個整數常量表達式。

[C99: 6.7.8/4]:具有靜態存儲持續時間的對象的初始化器中的所有表達式都應該是常量表達式或字符串文字。

z由於您在全局範圍聲明瞭靜態存儲持續時間,因此具有靜態存儲持續時間。如果您將其聲明移入函數中,則此規則不適用。

無名字abc資格作爲常量表達式,儘管你使用的const

[C99: 6.6/8]:算術常量表達式應有算術類型,並應只能有一個是整型常量操作數,浮點常量,枚舉常量,字符常量和sizeof表達式。算術常數表達式中的演算算符只能將算術類型轉換爲算術類型,除了作爲結果爲整數常量的sizeof運算符的操作數的一部分外。

雖然struct _S只是包裝了一個uint,這並不意味着它一個uint。事實上,關於struct _Z,你斷言「該結構只是一個整數陣列」是錯誤的:你沒有考慮類型。

C++在這方面比C要寬鬆得多,尤其是在constexpr時代。

+0

我沒有解決方案(除了移動初始化),但這是原因。 –

+0

非常感謝你,我期待着這是不可能的。 – Zirafinu