Lolo
Lolo

Reputation: 4169

How to modify the argument of a multi-argument macro?

I have various kinds of printf macros in my code defined along those lines:

#define DEBUG(...) printf(__VA_ARGS__)

This works well:

DEBUG("Hello %d",1);

will be the same as

printf("Hello %d",1);

Now can I make my macro also edit the args that are passed in to, say, add a \n at the end of the first argument? I.e. so that

DEBUG("Hello %d",1);

turns into

printf("Hello %d\n",1);

Upvotes: 2

Views: 204

Answers (3)

Jean Jung
Jean Jung

Reputation: 1210

If you want your \n to be always on the final, you can just add one more printf statement:

#define DEBUG(...) printf(__VA_ARGS__); printf("\n")
...
DEBUG("hello %d", 1);
DEBUG("hello %d", 1);

Outputs:

hello 1

hello 1

As pointed out by the others, this won't work as expected with this scenario:

if (cond) 
    DEBUG("Blah")

So you will have to define the macro this way:

#define DEBUG(...) do { printf(__VA_ARGS__); printf("\n"); } while(0)

Thanks to M. Oehm and undur_gongor

Upvotes: 4

undur_gongor
undur_gongor

Reputation: 15954

I suggest using:

#define DEBUG(fmt, ...) printf(fmt "\n", __VA_ARGS__)

The drawback is that you have to have at least one non-format string argument, i.e. you cannot use the macro as:

DEBUG("foo");

anymore.

For some compilers there are work-arounds allowing empty __VA_ARGS__ like

#define DEBUG(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)

in gcc (thanks to M. Oehm).

Upvotes: 4

Chris Beck
Chris Beck

Reputation: 16224

You could do this with string literal concatenation, if you know that the first argument is always a string literal.

If you have a macro

#define EXAMPLE(A,B) \
printf("%s", A B)

then in code

EXAMPLE("foo ", "bar\n");

would be the same as

printf("%s", "foo bar\n");

(Since you didn't show full code, I assume you can adapt this to your case)

Upvotes: 0

Related Questions