logoalt Hacker News

shawnz10/11/20243 repliesview on HN

For the unfamiliar, what does this pattern do exactly?


Replies

enriquto10/11/2024

In that case it's just to convert the value of a macro into a string constant

   cat > a.c
   #define X(s) #s
   #define S(s) X(s)
   char *f(void) return { S(A); }
   ^D

   cc -E a.c
   char *f(void) return { "A"; }
   
   cc -DA=B -E a.c
   char *f(void) return { "B"; }

More interestingly, you can use this trick to create code where some user-specified word appears as a string and as the name of the function. Exercice: write a macro M(x) such that compiling the code

    M(foo)
    M(bar)
results in

    void print_foo(void) { puts("foo"); }
    voir print_bar(void) { puts("bar"); }
show 1 reply
ahartmetz10/11/2024

It turns a macro argument into a string of that argument. Let's say you have a mydebug(expression) macro that should print both "expression" and the value of expression.

jjnoakes10/11/2024

The macro X turns its argument into a string, but using it on its own means you can't turn other macro values into strings, only macro names.

    #define F 42
    #define X(s) #s
    X(5)  //  Expands to "5" (as a string literal)
    X(F)  //  Expands to "F" not "42"
If you add one level of recursive macro expansion, though, that expands the macro argument as well as the macro definition:

    #define F 42
    #define X(s) #s
    #define S(s) X(s)
    S(5) // "5" as expected
    S(F) // "42" because S(F) expands to X(42) expands to "42"