0

c89 gcc 4.7.4

I was just experimenting with macros like these:

#define LOG_INFO_1(fmt, ...) printf(fmt, __VA_ARGS__)
#define LOG_INFO_2(...) printf(__VA_ARGS__)

And using like this:

LOG_INFO_1("%s:%d", __func__, __LINE__);
LOG_INFO_2("%s:%d", __func__, __LINE__);

The output gives exactly the same format. I am just wondering what is the advantage of having the fmt argument in my first macro? It doesn't seem to be really needed. How could I make use of it?

Cœur
  • 37,241
  • 25
  • 195
  • 267
ant2009
  • 27,094
  • 154
  • 411
  • 609
  • 2
    There is a difference if you only want to pass the format string, e.g. `LOG_INFO_1("just a simple string")`. When you do that, `LOG_INFO_1` will result in a compiler error, due to the trailing comma in the call to `printf` (since `__VA_ARGS__` expands to the empty string in that case), whereas `LOG_INFO_2` will expand correctly. – Adam Rosenfield Oct 23 '12 at 17:16

3 Answers3

5

Specifying that the first parameter is fmt makes no difference to the compiler/computer.

However, I think it makes a big difference to other programmers who may use your code.

Looking at LOG_INFO_1(fmt, ...), I see a strong hint that this macro takes a printf-style format string with additional parameters after.

Looking at LOG_INFO_2(...), I have no idea what parameters should be passed, or in what order. Maybe the first parameter should be a RFC 5424 severity code? Maybe it should be an output stream to write to? Nothing in the macro hints at the answer.

I think you should make work easier for the programmers who come after you by specifying as much as possible, and only leaving ambiguities such as ... only where absolutely necessary.

Community
  • 1
  • 1
abelenky
  • 63,815
  • 23
  • 109
  • 159
2

For macros it does not matter which variation you use. The preprocessor will produce the same C code from both macros.


For variadic functions at least one argument needs to be defined.

So

void foo(const char * fmt, ...);

would compile, whereas

void bar(...);

wouldn't.

alk
  • 69,737
  • 10
  • 105
  • 255
1

Take a look at ACE_DEBUG/Log_Msg. ACE (adaptive communications environment) is an established c++ framework for networking. They've implemented a thread-safe logging architecture using macros and variadic variables in a similar way.

count0
  • 2,537
  • 2
  • 22
  • 30