2016-10-28 13 views
0

私は、複雑な構造のフィールドを初期化するマクロを書き込もうとしています。この構造体では、一部のメンバは、実際のアドレスで時々初期化したいポインタであり、場合によってはNULLになります。次のように 構造を簡素化することができます。なぜこの静的ポインタへの初期化は無効ですか?

#define INIT_STRUCT(x) {&(x)} 

と使用方法は、次のようになります:マクロで

typedef struct { 
int * p; 
} MYSTRUCT; 

私の最初のパスでした

static int foo; 
static MYSTRUCT struct1 = INIT_STRUCT(foo); 

私は初期化するときにこれがうまく機能します実際のポインタに戻すことはできませんが、次のように動作しません。

static MYSTRUCT struct2 = INIT_STRUCT(NULL); 
コンパイラ(justifiably)フラグ&をエラーとして開発したため、 {&(NULL)}と開発されたため、

となりました。 私は&をマクロ本体の一部ではなく引数の一部として使うことができると知っていますが、これは私の場合は便利ではないし、コンパイラが勝つということも受け入れることができないので、マクロの以下の第二版:

static void * NOTHING; 
#define INIT_STRUCT(x) {&NOTHING == &(x) ? NULL : &(x)} 

用法

MYSTRUCT struct1 = INIT_STRUCT(foo); 
MYSTRUCT struct2 = INIT_STRUCT(NOTHING); 

しかし「初期化子が定数ではありません」というコンパイラの抗議。 &NOTHING == &(x)1 == 2に置き換えてもエラーはないので、条件のフォーマットは問題ではありません。 一方、&NOTHINGおよび&(foo)は、それ自体でイニシャライザとして有効です。

"スマート"マクロを無効にするコンパイラは正しいですか? &をfooの引数の一部として書くことを除いて、他に解決策はありますか?

コンパイラはMicrosoft Visual Studio C 2010 Ultimateです。

+4

として使用されます'?何が起こっているのかはコードの読者にとってより透過的で、もちろんNULLを使用することであなたの問題を解決できます。 –

+1

@Someprogrammerdudeが言ったことに加えて、2つのマクロを定義することもできます。 1つは一般的なケース、もう1つは特殊なケースです。マクロの柔軟性があまり高くなく、後で他の問題を引き起こす可能性があるため、マクロをあまりにも「スマート」にするのは避けてください。 – user694733

答えて

1

これを簡略化して使用することができます。

#define INIT_STRUCT(str, x) {str -> p = x} 

これはなぜ単に `(X){(x)}の#define INIT_STRUCT`として `INIT_STRUCT`マクロを定義し、` INIT_STRUCT(&FOO)としてそれを使用しない

INIT_STRUCT(struct1, foo); 
INIT_STRUCT(struct2, NULL); 
+0

これは割り当てであり、初期化ではありません。したがって、 'const'変数では動作しません。 – user694733

関連する問題