3
gcc (GCC) 4.7.2
c89

Is it possible to stringify a variadic macro?

I have the following macro and I want to output the resulting string from the fmt and arguments.

#define ERROR_MESSAGE(priority, fmt, ...)        \
    do {                                         \
        MODULE_LOG(priority, fmt, ##__VA_ARGS__);\
} while(0)

So, I just want to get the complete string of the fmt and the ##__VA_ARGS__ so I can assign it to a char * to perform some additional operations on it.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ant2009
  • 27,094
  • 154
  • 411
  • 609
  • 1
    The double-hash is the concatenation operator, not the stringify operator which is a single hash. – Some programmer dude Apr 26 '13 at 05:35
  • 2
    Variadic macros was introduced in C99 – David Ranieri Apr 26 '13 at 05:37
  • 1
    @JoachimPileborg: that use of `##` is a GCC extension which erases the comma before the `##` if the `__VA_ARGS__` list is empty. There's a question about that somewhere on SO; I came across the notation in an answer I was rereading recently. (One x-ref is [Macro definition](http://stackoverflow.com/questions/7788850/macro-definition/7788888#7788888); a better one is [C #define macro for debug printing](http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing/1644898#1644898).) – Jonathan Leffler May 07 '13 at 04:50

1 Answers1

6

Um, no. Preprocessing happens before the code is even compiled. It exists in a completely different universe from the executing program. One thing you can do, is run just the pre-processing step and examine the output (use the gcc switch -E to print the preprocessor output).

About the most you can do is to redirect this to a file, and then read the file in the program.


On further thought, let me back-off from "no", and change it to "maybe". Take a look at this other answer of mine, that implements a "foreach" macro for variadic macros.

So, using APPLYXn (and, implicitly, PPNARG), you could apply a STR(x) #x macro to the args like this (n.b. as written, APPLYXn can handle up to 15 arguments):

#define X(x) #x
#define ERROR_MESSAGE(priority, fmt, ...)        \
    "do {MODULE_LOG(" X(priority) X(fmt) APPLYXn(__VA_ARGS__) ");} while(0)"

int main() {
    printf("%s\n", ERROR_MESSAGE(3, "%d", 5) );
    return 0;
}

gcc -E produces

# 1 "strvar.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "strvar.c"
# 71 "strvar.c"

int main() {
    printf("%s\n", "do {MODULE_LOG(" "3" "\"%d\"" "5" ");} while(0)" );
    return 0;
}

And the compiler will concatenate all these string literals into one string.

Community
  • 1
  • 1
luser droog
  • 18,988
  • 3
  • 53
  • 105