Reputation: 516
I am trying to write a macro to initialize fields of a complex structure. In this structure, some member is a pointer which I want to initialize sometimes with a real address and sometimes to NULL
.
The structure can be simplified as follows:
typedef struct {
int * p;
} MYSTRUCT;
My first pass at the macro was:
#define INIT_STRUCT(x) {&(x)}
and the usage would be:
static int foo;
static MYSTRUCT struct1 = INIT_STRUCT(foo);
This works well when I initialize to a real pointer, but the following does not work:
static MYSTRUCT struct2 = INIT_STRUCT(NULL);
because it is developed as {&(NULL)}
and the compiler (justifiably) flags having & on a constant as an error.
I know that I could choose to have the & as part of the argument and not part of the macro body, but this is not convenient in my case, and also I cannot accept that the compiler wins, so I tried to be smarter with the following second version of the macro:
static void * NOTHING;
#define INIT_STRUCT(x) {&NOTHING == &(x) ? NULL : &(x)}
with usage
MYSTRUCT struct1 = INIT_STRUCT(foo);
MYSTRUCT struct2 = INIT_STRUCT(NOTHING);
However the compiler protests that "initializer is not a constant".
If I replace &NOTHING == &(x)
by 1 == 2
, there is no error, so the format of a condition is not the problem.
On the other hand, &NOTHING
and &(foo)
are valid as initializers by themselves.
Is the compiler correct in invalidating my "smarter" macro? Is there any other solution, except writing the & as part of the argument for foo?
The compiler is Microsoft Visual Studio C 2010 Ultimate.
Upvotes: 0
Views: 118
Reputation: 8614
You can simplify and use this.
#define INIT_STRUCT(str, x) {str -> p = x}
This is used as
INIT_STRUCT(struct1, foo);
INIT_STRUCT(struct2, NULL);
Upvotes: 1