我想寫一個宏來初始化複雜結構的字段。在這種結構中,某些成員是我想用有效地址初始化的指針,有時候是NULL
。 結構可以如下簡化:爲什麼初始化爲靜態指針無效?
typedef struct {
int * p;
} MYSTRUCT;
我在宏觀第一遍是:
#define INIT_STRUCT(x) {&(x)}
和用法是:
static int foo;
static MYSTRUCT struct1 = INIT_STRUCT(foo);
這個效果很好,當我初始化到一個真正的指針,但以下不起作用:
static MYSTRUCT struct2 = INIT_STRUCT(NULL);
,因爲它是作爲{&(NULL)}
開發的,編譯器(有理)標記爲&作爲錯誤常量。 我知道我可以選擇將&作爲參數的一部分,而不是宏觀主體的一部分,但這在我的情況下並不方便,也不能接受編譯器的勝利,所以我試圖變得更聰明下面的第二個版本的宏:
static void * NOTHING;
#define INIT_STRUCT(x) {&NOTHING == &(x) ? NULL : &(x)}
與使用
MYSTRUCT struct1 = INIT_STRUCT(foo);
MYSTRUCT struct2 = INIT_STRUCT(NOTHING);
但是編譯器抗議「初始化不是一個常量」。 如果我用1 == 2
代替&NOTHING == &(x)
,則沒有錯誤,所以條件的格式不是問題。 另一方面,&NOTHING
和&(foo)
本身作爲初始值設定項是有效的。
編譯器在使我的「智能」宏無效時是否正確? 除了將&作爲foo參數的一部分外,還有其他解決方案嗎?
該編譯器是Microsoft Visual Studio C 2010 Ultimate。
爲什麼不能簡單定義'INIT_STRUCT'宏如'的#define INIT_STRUCT(X){(X)}',並且使用它作爲'INIT_STRUCT(富) '?對於代碼讀者而言,它會對所發生的事情更加透明,當然可以通過使用NULL來解決您的問題。 –
除了@Someprogrammerdude所說的,你還可以定義2個宏;一個用於普通情況,一個用於特殊情況。應該避免使用宏來實現「智能」,因爲宏不是非常靈活,並且可能在以後導致其他問題。 – user694733