Alexandru
Alexandru

Reputation: 25810

gcc warnings for no-effect statements.

I have a logging macro which in release mode becomes:

#define LOG (void)

So statement

LOG("foobar %d", 0xbabecafe);

is expanded to

(void)("foobar %d", 0xbabecafe);

The problem is that the last expression produces an warning under gcc:

warning: left-hand operand of comma expression has no effect [-Wunused-value]

How can I change the logging macro such that no warning is issued? (Note, that I don't want to add compiling flag -Wunused-value).

EDIT I see already a couple of answers involving (...). The same file is compiled under Minix which doesn't support variadic macros. The best would be to have a C89 conforming solution. While your answer is correct (and I upvoted it), it is my fault that I didn't include this small detail.

Upvotes: 6

Views: 8162

Answers (5)

Evan Teran
Evan Teran

Reputation: 90483

I think the old school way of dealing with this is to take advantage of double parens. Something like this:

LOG(("message: %d", 10));

Then for your macro, you define it like this:

#define LOG(x) printf x

or

#define LOG(x) (void)0

Because of the double parens, the pre-processor treats the whole inner paren as a single parameter. This at least used to work in visual studio.

EDIT: I did a quick test, it works with gcc with -ansi, so it should be good:

gcc -DNDEBUG -ansi -pedantic -W -Wall test.c -o test

#include <stdio.h>

#ifdef NDEBUG
#define LOG(x) printf x
#else
#define LOG(x) (void)0
#endif

int main() {
    LOG(("message: %d\n", 10));
    return 0;
}

Upvotes: 6

dmuir
dmuir

Reputation: 644

I've used

#define LOG( t) t

for the development version and

#define LOG( t)

for the release version, with a typical use being

LOG( printf( "here\n"));

Upvotes: 1

Jens Gustedt
Jens Gustedt

Reputation: 78943

For your problems with a non-conforming C implementation (not even C89?) you could do something like

static void LOG(char *format, ...) { /* empty */ }

even a completely dumb compiler should be able to optimize that out.

Upvotes: 2

Martin Wickman
Martin Wickman

Reputation: 19925

#define LOG(...) seems to do the trick.

Upvotes: 3

Jan Hudec
Jan Hudec

Reputation: 76306

The easiest should be

#define LOG(...) (void)0

(gcc supports the C99 variadic macros and most other compilers also do these days) That will discard the arguments list, which has two advantages:

  • it does not create statements with no effect and
  • the arguments are not evaluated at all (if you call non-inline functions in the argument list, in your version the compiler can't eliminate them, while with the variadic macro, the compiler won't see them at all.

Upvotes: 6

Related Questions