我正在尝试编写一个宏来初始化复杂结构的字段。在这个结构中,一些成员是一个指针,我想有时用真实地址初始化,有时候用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);
然而,编译器抗议“初始化程序不是常量”。
如果我将&NOTHING == &(x)
替换为1 == 2
,则没有错误,因此条件的格式不是问题。
另一方面,&NOTHING
和&(foo)
本身有效作为初始值。
编译器是否正确使我的“更智能”宏无效? 有没有其他解决方案,除了写&作为foo参数的一部分?
编译器是Microsoft Visual Studio C 2010 Ultimate。
答案 0 :(得分:1)
您可以简化并使用它。
#define INIT_STRUCT(str, x) {str -> p = x}
用作
INIT_STRUCT(struct1, foo);
INIT_STRUCT(struct2, NULL);