0

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.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ozawa Tomohiko
  • 157
  • 1
  • 1
  • 7
  • ... I do not understand why you are using macros! – Ed Heal Nov 22 '15 at 08:47
  • You are using two gcc extensions, which you shouldn't if you want to write portable code: `args...` to name the arguments and `##args` to eat a comma. I think the reason why the two have different behavior is obvious. Your second variant has `err` after the `##args` construct, so it needs it. I am not familiar enough with gcc specifics to help you to correct this. But you should perhaps search SO for "debugging macro" or so to find portable code for this. Similar questions pop up once in a while. – Jens Gustedt Nov 22 '15 at 08:58

1 Answers1

2

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__)
simpel01
  • 1,792
  • 12
  • 13