2016-11-29 46 views
4

我試圖靜態分配一些結構,每個結構包含兩個成員:一個指向結構數組的指針,以及該數組的大小。sizeof複合文字數組

下面的代碼的工作版本:

#define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0])) 

struct conf_element { 
     char *key; 
     enum conf_elem_type val_type; 
     void *val_p; 
     tok_t *(*fn_p)(const char *js, jsmntok_t *tok); 
}; 

struct conf_schema { 
     struct conf_element *conf_elems; 
     size_t size; 
}; 

struct conf_element conf_schema_antennae_elems[] = { 
     {"key1_nm", LEAF_INT, NULL, NULL}, 
     {"key2_nm", LEAF_INT, NULL, NULL} 
}; 

struct conf_schema conf_schema_antennae = { 
     conf_schema_antennae_elems, 
     ARRAY_SIZE(conf_schema_antennae_elems) 
}; 

但是,而不是單獨地限定所述陣列,然後限定結構時引用該陣列,我想以與陣列以便文本初始化該指針包含這一切爲的是什麼,我相信着想結構定義中增加可讀性:

struct conf_schema conf_schema_antennae = { 
     (struct conf_element []) { 
       {"key1_nm", LEAF_INT, NULL, NULL}, 
       {"key2_nm", LEAF_INT, NULL, NULL} 
     }, 
     /* the size of that^compound literal goes here */ 
}; 

是否可以自動獲得該數組在編譯時文字的大小? (還是我濫用語言,使事情更難比他們應該是什麼?)

編輯: 基於Olaf的回答類似的問題和約翰·布林的評論,這是我結束了:

#define S(arr) {arr, ARRAY_SIZE(arr)} 

struct conf_schema conf_schema_antennae = S((
     (struct conf_element []) { 
       {"key1_nm", LEAF_INT, NULL, NULL}, 
       {"key2_nm", LEAF_INT, NULL, NULL} 
     } 
)); 

#undef S 
+4

的可能的複製(http://stackoverflow.com/questions/35753494/can-i- reduce-a-long-array-initialization-to-a-short-initializer-list-in-c) – Olaf

+2

如果根據需要將問題分解爲[mcve],最終會出現重複。我仍然認爲我的答案是最清楚和最簡單的解決方案。只要採納你的問題。如果字段不被修改,你應該使用'const'限定符(正確!)。 – Olaf

+1

這裏唯一可能的竅門是,當它用作宏的參數(如Olaf在其引用的答案中描述)時,需要將數組文字括在(額外)括號中。括號會阻止文字本身的逗號作爲宏參數分隔符。 –

回答

1

你不知道複合文字數組的大小,因爲它的變量名是隱藏的。

另外struct conf_element *conf_elems是一個指針,宏ARRAY_SIZE無法測量真實數組的長度。

如果使用-g進行編譯,您可以看到隱藏變量的名稱。它將在可執行文件的調試信息中顯示一個名爲__compond_literal.###的變量。

我建議你一個解決方法:你真的需要知道它在客戶端代碼中的大小嗎? 如果沒有,試試這個:[?我可以減少長數組初始化在C短初始化列表]

struct conf_schema conf_schema_antennae = { 
     (struct conf_element []) { 
       {"key1_nm", LEAF_INT, NULL, NULL}, 
       {"key2_nm", LEAF_INT, NULL, NULL}, 
       {0, 0, 0, 0} /* Place holder for the end of the array */ 
     } 
}; 

void client_code() 
{ 
    struct conf_element *p_elems = conf_schema_antennae.conf_elems; 

    while (p_elems->key) 
    { 
    /* ... */ 
    p_elems++; 
    } 
}