Я пытаюсь написать макрос для инициализации полей сложной структуры. В этой структуре некоторый член является указателем, который я хочу инициализировать иногда с реальным адресом, а иногда и с 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.
Почему бы не просто определить 'INIT_STRUCT' макрос как' #define INIT_STRUCT (х) {(х)} ', и использовать его как' INIT_STRUCT (& Foo) '? Это будет более прозрачно для читателей кода, что происходит, и, конечно же, решит вашу проблему с помощью 'NULL'. –
В дополнение к тому, что сказал @Someprogrammerdude, вы также можете определить 2 макроса; один для обычного случая и один для специального случая. Следует избегать слишком «умных» с макросами, поскольку макросы не очень гибкие и могут вызвать другие проблемы позже. – user694733