GCC предупреждения для безрезультатных утверждений. - PullRequest
4 голосов
/ 29 июля 2011

У меня есть макрос регистрации, который в режиме выпуска становится:

#define LOG (void)

Итак, заявление

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

расширен до

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

Проблема в том, что последнее выражение выдает предупреждение под gcc:

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

Как я могу изменить макрос ведения журнала, чтобы не выводилось предупреждение? (Обратите внимание, что я не хочу добавлять флаг компиляции -Wunused-value).

РЕДАКТИРОВАТЬ Я вижу уже пару ответов, касающихся (...). Этот же файл скомпилирован под Minix, который не поддерживает вариационные макросы. Лучше всего было бы иметь соответствующее решение C89. Хотя ваш ответ правильный (и я проголосовал за него), я виноват, что не включил эту маленькую деталь.

Ответы [ 5 ]

6 голосов
/ 29 июля 2011

Я думаю, что старый способ борьбы с этим заключается в том, чтобы использовать преимущество двойных паренов.Примерно так:

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

Затем для вашего макроса вы определяете его так:

#define LOG(x) printf x

или

#define LOG(x) (void)0

Из-за двойных паренов,препроцессор рассматривает весь внутренний парен как один параметр.Это, по крайней мере, раньше работало в visual studio.

EDIT : я сделал быстрый тест, он работает с gcc с -ansi, так что должно быть хорошо:

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;
}
6 голосов
/ 29 июля 2011

Самое простое должно быть

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

(gcc поддерживает переменные макросы C99, и большинство других компиляторов также делают это в наши дни). Это исключит список аргументов, который имеет два преимущества:

  • он не создает операторов без эффекта, а
  • аргументы вообще не оцениваются (если вы вызываете не встроенные функции в списке аргументов, в вашей версии компилятор не может их исключить, ас переменным макросом компилятор их вообще не увидит.
3 голосов
/ 29 июля 2011

#define LOG(...) кажется, добивается цели.

2 голосов
/ 29 июля 2011

Для ваших проблем с несоответствующей реализацией C (даже не C89?) Вы можете сделать что-то вроде

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

даже совершенно тупой компилятор должен быть в состоянии оптимизировать это.

1 голос
/ 29 июля 2011

Я использовал

#define LOG( t) t

для версии для разработки и

#define LOG( t)

для версии выпуска, обычно используется

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