cx-macros

C - How to assign a value inside my macro?


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?


Solution

  • You need to look into the preprocessed form of your code in your source file slethoprod.c. With GCC, you can get it with gcc -C -E slethoprod.c > slethoprod.i then inspect (with an editor or a pager) that slethoprod.i file.

    It contains stuff like:

    struct_t a; a.a = 33; struct_t b; b.a = 33;
    

    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

    struct_t a = {33};
    

    or even (for readability purposes) a struct initialization like

    struct_t b = {.a=33};
    

    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.