Search code examples
cc-preprocessorstringify

Compile errors when accessing a structure element using stringified name


I'm trying to construct a bunch of functions which access elements of a structure. I'm using the # stringify preprocessor directives to construct function names ending in the element name, and inside those function access the element. This will allow calling a bunch of simple macros to create some very similar functions.

When compiling the following simplified example, I get a compiler error

struct test
{
    float tst;
}test;

// Macro that creates callback functions
#define test_float_(varname) \
void test_float_##varname(void) {\
    test.#varname = 0;\
}

test_float_(tst)
error: expected identifier before string constant
 test_float_(tst)
                ^
../protocol.c:66:8: note: in definition of macro 'test_float_'
  test.#varname = 0;\

If I remove the test.#varname = 0; line, then the error goes away.
What am I doing wrong here?


Solution

  • # MacroArgument creates a string literal out of a macro argument.

    Your code:

    struct test
    {
        float tst;
    }test;
    
    // Macro that creates callback functions
    #define test_float_(varname) \
    void test_float_##varname(void) {\
        test.#varname = 0;\
    }
    
    test_float_(tst)
    

    preprocesses to (https://gcc.godbolt.org/z/ZkaKaA):

    struct test
    {
        float tst;
    }test;
    
    void test_float_tst(void) { test."tst" = 0;}
    

    The test."tst" = 0; part is obviously a syntax error. Lose the # before varname and it'll work.

    (Note: The -E flag given to a POSIX C compiler causes it to just run the preprocessor, textually. You'll find it useful in debugging C macros.)