Как подавить предупреждения "неиспользуемый параметр" в C?


например:

Bool NullFunc(const struct timespec *when, const char *who)
{
   return TRUE;
}

В C++ я смог поставить /*...*/ комментарий вокруг параметров. Но не в C конечно, где это дает мне ошибку error: parameter name omitted.

11 165

11 ответов:

обычно я пишу такой макрос:

#define UNUSED(x) (void)(x)

Вы можете использовать этот макрос для всех ваших неиспользуемые параметры. (Обратите внимание, что это работает на любом компиляторе.)

например:

void f(int x) {
    UNUSED(x);
    ...
}

в gcc вы можете пометить параметр с помощью unused атрибут.

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

на практике это достигается путем сдачи __attribute__ ((unused)) сразу после параметра. Например

auto lambda = [](workerid_t workerId) -> void { };

становится

auto lambda = [](__attribute__((unused)) _workerid_t workerId) -> void { } ;

вы можете использовать неиспользуемый атрибут gcc/clang, однако я использую эти макросы в заголовке, чтобы избежать наличия определенных атрибутов gcc по всему источнику, а также иметь __attribute__ везде немного многословно / некрасиво.

#ifdef __GNUC__
#  define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
#  define UNUSED(x) UNUSED_ ## x
#endif

#ifdef __GNUC__
#  define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
#else
#  define UNUSED_FUNCTION(x) UNUSED_ ## x
#endif

затем вы можете сделать...

void foo(int UNUSED(bar)) { ... }

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

и функции...

static void UNUSED_FUNCTION(foo)(int bar) { ... }

Примечание 1):
Насколько я знаю, MSVC не имеет эквивалента __attribute__((__unused__)).

примечание 2):
Элемент UNUSED макрос не будет работать для аргументов, которые содержат скобки,
так что если у вас есть аргумент типа float (*coords)[3] вы не могу а,
float UNUSED((*coords)[3]) или float (*UNUSED(coords))[3], это единственный недостаток UNUSED макрос я нашел до сих пор, в этих случаях я возвращаюсь к (void)coords;

С gcc с неиспользуемым атрибутом:

int foo (__attribute__((unused)) int bar) {
    return 0;
}

маркировка атрибута является идеальным способом. Макрос приводит к некоторой путанице. и с помощью void (x) мы добавляем накладные расходы на обработку.

если не используется входной аргумент, используйте

void foo(int __attribute__((unused))key)
{
}

Если не использовать переменную, определенную внутри функции

void foo(int key)
{
   int hash = 0;
   int bkt __attribute__((unused)) = 0;

   api_call(x, hash, bkt);
}

теперь позже с помощью хэш-переменной для вашей логики, но не нужно bkt. определить БКТ пустыми, в противном случае компилятор говорит'bkt набор BT не используется".

Примечание: это просто для подавления предупреждение не для оптимизации.

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

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
<code with unused parameters here>
#pragma GCC diagnostic pop

у меня та же проблема. Я использовал третью часть библиотеки. Когда я компилирую эту библиотеку, компилятор (gcc / clang) будет жаловаться на неиспользуемые переменные.

такой

в MSVC для подавления конкретного предупреждения достаточно указать его номер компилятору как /wd#. Мои CMakeLists.txt содержит такой блок:

If (MSVC)
    Set (CMAKE_EXE_LINKER_FLAGS "$ {CMAKE_EXE_LINKER_FLAGS} / NODEFAULTLIB: LIBCMT")
    Add_definitions (/W4 /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127)
    Add_definitions (/D_CRT_SECURE_NO_WARNINGS)
Elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
    Add_definitions (-Wall -W -pedantic)
Else ()
    Message ("Unknown compiler")
Endif ()

теперь я не могу сказать, что именно /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127 означает, потому что я не обращаю никакого внимания на MSVC в течение трех лет, но они подавляют суперпедантические предупреждения, которые не влияют на результат.

Я видел этот стиль используется:

if (when || who || format || data || len);

видя, что это помечены как gcc, вы можете использовать переключатель командной строки Wno-unused-parameter.

например:

gcc -Wno-unused-parameter test.c

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

для записи Мне нравится ответ Job выше, но мне интересно решение, просто используя имя переменной само по себе в заявлении" ничего не делать":

void foo(int x) {
    x; /* unused */
    ...
}

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

преимущество заключается в том, что определение не требуется, и он избавляется от предупреждения.

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