Подавить предупреждение о неиспользуемой переменной в C ++ => Ошибка компилятора или ошибки кода? - PullRequest
11 голосов
/ 15 декабря 2009

В настоящее время я использую следующий шаблон функции для подавления предупреждений о неиспользуемых переменных:

template<typename T>
void
unused(T const &) {
  /* Do nothing. */
}

Однако при портировании на cygwin из Linux я теперь получаю ошибки компилятора на g ++ 3.4.4 (В Linux я 3.4.6, так что, возможно, это исправление ошибки?):

Write.cpp: In member function `void* Write::initReadWrite()':
Write.cpp:516: error: invalid initialization of reference of type 'const volatile bool&' from expression of type 'volatile bool'
../../src/common/Assert.h:27: error: in passing argument 1 of `void unused(const T&) [with T = volatile bool]'
make[1]: *** [ARCH.cygwin/release/Write.o] Error 1

Аргументом к unused является переменная-член, объявленная как:

  volatile bool readWriteActivated;

Это ошибка компилятора или ошибка в моем коде?

Вот минимальный тестовый пример:

template<typename T>
void unused(T const &) { }

int main() {
  volatile bool x = false;
  unused(!x); // type of "!x" is bool
}

Ответы [ 5 ]

28 голосов
/ 15 декабря 2009

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

int f(int a, float) {
     return a*2;
}

будет компилироваться везде со всеми включенными предупреждениями, без предупреждения о неиспользованном поплавке. Даже если аргумент имеет имя в прототипе (например, int f(int a, float f);), он все равно не будет жаловаться.

9 голосов
/ 15 декабря 2009

Я не уверен на 100%, что это переносимо, но это та идиома, которую я обычно использовал для подавления предупреждений о неиспользуемых переменных. Здесь контекст является обработчиком сигнала, который используется только для перехвата SIGINT и SIGTERM, поэтому, если функция когда-либо вызывается, я знаю, что пора программе выйти.

volatile bool app_killed = false;
int signal_handler(int signum)
{
    (void)signum; // this suppresses the warnings
    app_killed = true;
}

Мне не нравится загромождать список параметров с помощью __attribute__((unused)), поскольку трюк приведения к пустоте работает без обращения к макросам для Visual C ++.

4 голосов
/ 16 декабря 2009

Это ошибка компилятора, и нет известных обходных путей:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42655

Исправлено в v4.4.

2 голосов
/ 15 декабря 2009

В GCC вы можете определить макрос следующим образом:

#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif 

Любые параметры, отмеченные этим макросом, будут подавлять неиспользованное предупреждение, которое выдает GCC (и переименовывает параметр с префиксом UNUSED_). Для Visual Studio вы можете подавлять предупреждения с помощью директивы #pragma.

1 голос
/ 06 октября 2010

Ответ, предложенный haavee (измененный ur), - это тот ответ, который я обычно использую:

int f(int a, float /*epsilon*/) {
     return a*2;
}

Настоящая проблема возникает, когда аргумент иногда , но не всегда используется в методе, например ::

int f(int a, float epsilon) {
#ifdef LOGGING_ENABLED
     LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
     return a*2;
}

Теперь я не могу закомментировать имя параметра epsilon, потому что это нарушит мою сборку журналирования (я не хочу вставлять еще один #ifdef в список аргументов, потому что это делает код намного труднее для чтения).

Так что я думаю, что лучшим решением было бы использовать предложение Тома:

int f(int a, float epsilon) {
(void) epsilon;    // suppress compiler warning for possibly unused arg
#ifdef LOGGING_ENABLED
     LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
     return a*2;
}

Меня беспокоит только то, что некоторые компиляторы могут предупреждать о "(пустом) эпсилоне;" заявление, например предупреждение «оператор не имеет никакого эффекта» или что-то подобное - я думаю, мне просто нужно протестировать все компиляторы, которые я, скорее всего, буду использовать ...

...