Search code examples
cgccc-preprocessorvariadic-macros

C variadic macro


I defined two variadic macros below for debug printing.

#define MYTRACE(fmt, args...) printf("%s(): "fmt"\n", __func__, ##args)
#define MYTRACE_ERR(err, fmt, args...) printf("[ERR] %s(): "fmt" err=%d\n", __func__, ##args, err)

Second is the one who shows not only a message but the error code given to the first argument. Using them, I wrote the following code.

int main(void) {
    int err = 0;

    MYTRACE("this is test, err=%d.", err);
    MYTRACE();
    MYTRACE_ERR(err, "error!");
    MYTRACE_ERR(err);        // This becomes error.
    MYTRACE_ERR(err, "");    // This is OK.
}

This code cannot be compiled because MYTRACE_ERR(err); becomes macro usage error, but MYTRACE(); is not. To avoid error, MYTRACE_ERR seems to require at least two arguments.

I don't understand why the MYTRACE works even though no argument is given, but MYTRACE_ERR does not work if two arguments are not given.


Solution

  • According to : https://gcc.gnu.org/onlinedocs/cpp/Macro-Arguments.html

    You can leave macro arguments empty; this is not an error to the preprocessor (but many macros will then expand to invalid code). You cannot leave out arguments entirely; if a macro takes two arguments, there must be exactly one comma at the top level of its argument list.

    Using MYTRACE_ERR(err,); will compile!

    Additionally the correct way of defining a variadic macro should be the following:

    #define MYTRACE(fmt, ...) printf("%s(): "fmt"\n", __func__, ##__VA_ARGS__)