Подавить предупреждение компилятора, объявленная функция никогда не упоминается

Итак, у меня есть такой код:

void foo (int, int);

void bar ( )
{
    //Do Stuff

   #if (IMPORTANT == 1)
       foo (1, 2);
   #endif

}

При выполнении компиляции без "ВАЖНО" я получаю предупреждение компилятора о том, что foo определена и на нее никогда не ссылаются. Что заставило меня задуматься (вот в чем проблема).

Так что, чтобы исправить это, я просто добавил то же самое #if (IMPORTANT == 1) вокруг определения функции и т. д.... чтобы удалить предупреждение, и затем я начал задаваться вопросом, есть ли другой способ подавить это предупреждение для этой функции. Я смотрел на "неиспользуемый" атрибут GCC и не знал, имеет ли функция тот же атрибут, который я мог установить? Есть ли еще какой-то способ подавить его, который подавляет это предупреждение только для этой функции, а не для файла?

8 ответов

Решение

... потом я начал задаваться вопросом, есть ли другой способ подавить это предупреждение для этой функции.

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

(void)foo; //don't call the function, just use it as function-pointer

Следует подавить это предупреждение.

Вы можете написать макрос:

#define SUPPRESS_WARNING(a) (void)a

void foo(int thisIsAlsoAnUnsedParameter, int usedParameter)
{
   SUPPRESS_WARNING(foo); //better do this inside the definition itself :D

   SUPPRESS_WARNING(thisIsAlsoAnUnsedParameter);
}

Как видите, определение foo Сам подавляет предупреждение.

В C++17 вы можете объявить свою функцию с помощью [[maybe_unused]]:

[[maybe_unused]] void foo (int, int);

Это подавит предупреждение и является правильным идиоматическим способом выражения возможно неиспользуемой функции в C++17.

Я вполне уверен, что соответствующий параметр предупреждения это:

-Wunused-функция
Предупреждать всякий раз, когда статическая функция объявлена, но не определена, или не встроенная статическая функция не используется. Это предупреждение включено -Wall.

Таким образом, предупреждение должно быть дано только для static функция, интересно. Имеет смысл. Если функция static он может использоваться только в текущем файле, поэтому его определение также должно быть в этом файле.

И объявив это static inline избегает предупреждения, не прибегая к уродливым макросам или специфическим для компилятора прагмам или атрибутам.

Одним из решений является использование атрибутов функций.

void foo (int, int) __attribute__ ((unused));

Это скажет gcc не выдавать предупреждение о неиспользуемой функции для функции. foo, Если вы беспокоитесь о переносимости, вы можете определить макрос UNUSED_FUNCTION_ATTRIBUTE что расширяется до __attribute__ ((unused)) с компиляторами, которые поддерживают атрибуты, но расширяются ни к чему другому.

Я нахожу способ сделать это во всем мире, и это работает также в c

#define SUPPRESS_UNUSED_WARN(var) \
    int _dummy_tmp_##var = ((int)(var) & 0)

тогда вы используете это как:

static int foo(int a, int b)
{
    // ....
}
SUPRESS_UNUSED_WARN(foo);
  • может использоваться для функций и глобальных переменных
  • он должен быть размещен глобально, чтобы работать
  • его нельзя использовать для локальных переменных

Хороший способ инкапсулировать вещи, зависящие от компилятора и системы, - это выделить их в заголовки. Затем вы настраиваете путь включения в зависимости от компилятора и системы и, возможно, других вещей. Вы можете сделать то же самое для файлов исходного кода.

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

// [foo.h]
#pragma once
void foo( int, int );

С файлом реализации

// [foo.cpp]
#include <foo.virtual.cpp>

Затем для сборки, где что-то должно произойти, добавьте к пути включения каталог, содержащий

// [foo.virtual.cpp]
#include <foo.h>
void foo( int const a, int const b )
{
    // Do the thing.
}

А для сборки, где ничего не должно происходить, добавьте к пути включения каталог, содержащий

// [foo.virtual.cpp]
#include <foo.h>
void foo( int, int ) {}

Если вы боитесь, что вызов пустой функции будет очень трудоемким, например, затрачивается нано-секунда, тогда просто переместите определения в заголовки и добавьте слово inline,

Если foo также используется для других целей, определить функцию bar который вызывает это для того, что должно быть или не должно происходить bar вместо для foo,

Затем вы удалили все материалы препроцессора.

Помните, что директивы препроцессора в коде плохие.

Для целевой платформы ARM при использовании компилятора ARM используйте следующую директиву компилятора вокруг целевой функции, чтобы подавить это предупреждающее сообщение:

#pragma diag_suppress 177
void foo(void)
{
/* does something but is not being called for the current build */
}
#define SUPPRESS_UNUSED_WARN(var) \
    int _dummy_tmp_##var = ((int)(var) & 0)

не работает в IAR, изменение на это будет работать:

#define SUPPRESS_UNUSED_WARN(var) \
     void _dummy_tmp_##var(void) { (void)(var); }

Вы также можете определить макрос _CRT_SECURE_NO_DEPRECATE в настройках проекта Visual Studio.

Перейти к свойствам проекта -> Свойства конфигурации -> C/C++ -> Препроцессор -> Определения препроцессора

Добавить _CRT_SECURE_NO_DEPRECATE.

Это оно.!

Другие вопросы по тегам