I am trying to assign a value inside my x-macro, but I don't really understand why it is not working:
#include <stdio.h>
typedef struct
{
int a;
int b;
} struct_t;
#define MY_LIST \
MY_ELEMENT(a) \
MY_ELEMENT(b)
#define MY_ELEMENT(x) struct_t x; \
x.a=33;
MY_LIST
#undef MY_ELEMENT
int main(void)
{
fprintf(stdout, "a: %d\n", a.a);
return 0;
}
When compiling this I get the following error:
test.c:14:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
x.a=33;
Could somebody explain why I am getting this error and how to solve this?
You need to look into the preprocessed form of your code in your source file
slethoprod.c
. With GCC, you can get it withgcc -C -E slethoprod.c > slethoprod.i
then inspect (with an editor or a pager) thatslethoprod.i
file.It contains stuff like:
which is obviously not valid C code (since it has some assignment outside of any function, at file scope; remember that an initialization in a declaration is not an assignment).
You might want to have some definition (with initialization) such as
or even (for readability purposes) a struct initialization like
and you could play fancy preprocessor tricks to get that.
Look into some C reference site and/or study the C11 standard n1570 to learn more about C. Read also the documentation of your compiler (e.g. GCC) and of your preprocessor (e.g. cpp).
BTW, I personally feel that naming a global with the same name
a
as some field in it is poor taste (even if it is legal, since field names and global variables have different namespaces). For readability purposes, I recommend avoiding that.Assigning values to structure fields outside of function scope isn't appropriate, so your original code doesn't work
If you want to use current macro, you should write like this:
Or you can change your macro this way:
#define MY_ELEMENT(x) struct_t x = {33, 0};
or even better this:
#define MY_ELEMENT(x) struct_t x = {.a = 33};
and leave the rest of your code as is.
So that way you will initialize your variable right in macro.
The error you are referring mainly happens when there is a
;
missing somewhere in code.In this case if you add
\
afterx.a=33;
and then callMY_LIST
it goes away.But then you should call
MY_LIST
in function fora
to be defined inmain
here is a working version of your code