2016-10-28 5 views
0

Я пытаюсь написать макрос для инициализации полей сложной структуры. В этой структуре некоторый член является указателем, который я хочу инициализировать иногда с реальным адресом, а иногда и с 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.

+4

Почему бы не просто определить 'INIT_STRUCT' макрос как' #define INIT_STRUCT (х) {(х)} ', и использовать его как' INIT_STRUCT (& Foo) '? Это будет более прозрачно для читателей кода, что происходит, и, конечно же, решит вашу проблему с помощью 'NULL'. –

+1

В дополнение к тому, что сказал @Someprogrammerdude, вы также можете определить 2 макроса; один для обычного случая и один для специального случая. Следует избегать слишком «умных» с макросами, поскольку макросы не очень гибкие и могут вызвать другие проблемы позже. – user694733

ответ

1

Вы можете упростить и использовать это.

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

Это используется как

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

Это назначение, а не инициализация. Таким образом, он не будет работать с переменными 'const'. – user694733

Смежные вопросы