如何在C中抑制"未使用的参数"警告?

nix*_*get 195 c gcc gcc-warning

例如:

Bool NullFunc(const struct timespec *when, const char *who)
{
   return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

在C++中,我能够对/*...*/参数进行评论.但当然不是在C中,它给了我错误error: parameter name omitted.

Job*_*Job 280

我经常写一个像这样的宏:

#define UNUSED(x) (void)(x)
Run Code Online (Sandbox Code Playgroud)

您可以将此宏用于所有未使用的参数.(请注意,这适用于任何编译器.)

例如:

void f(int x) {
    UNUSED(x);
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 我只是直接使用(void)x (38认同)
  • 我正在使用`#define UNUSED(...)(void)(__ VA_ARGS __)`这允许我将它应用于多个变量. (17认同)
  • @Alcott因为(在我的情况下)函数可能是许多必须具有相同签名的函数之一,因为它们被函数指针引用. (8认同)
  • 虽然这是AFAIK唯一的便携式方式,但如果您稍后使用该变量并忘记删除未使用的线路,则可能会产生误导.这就是为什么GCC的__unused__很好. (6认同)
  • @CookSchelling:啊但你不应该那样用它.做这样的事情:`void f(int x){UNUSED(x);}`. (6认同)
  • 如果使用多个变量,不要遇到*"警告:逗号表达式的左手操作数没有效果"*? (4认同)
  • @pasignature:我想说的是让你的代码不言自明。“UNUSED(argsv)”说明了它的作用,“(void)argsv”在我看来则不然。 (2认同)

Phi*_*ter 101

在gcc中,您可以使用unused属性标记参数.

附加到变量的此属性表示该变量可能未使用.GCC不会对此变量发出警告.

实际上,这是通过__attribute__ ((unused))在参数之前放置来实现的.例如:

void foo(workerid_t workerId) { }
Run Code Online (Sandbox Code Playgroud)

void foo(__attribute__((unused)) workerid_t workerId) { }
Run Code Online (Sandbox Code Playgroud)

  • 对于像我这样的新手,这意味着在参数前加上`__attribute __((unused))`. (24认同)
  • 将 GCC 中的扩展称为“专有”是,嗯,确实是这样。 (10认同)
  • @josch我认为您是完全正确的,但是文档似乎暗示应将其放在*参数之后。这两个选项都可能受支持而没有问题。 (2认同)
  • 另请注意,`__attribute__((unused))`是[专有的GCC扩展](/sf/answers/3326314281/)。它受到其他一些编译器的支持,但我认为这不适用于 MSVC。但它并不是编译器标准的直接一部分,因此它不如其他一些选项那么可移植 (2认同)

ide*_*n42 57

你可以使用gcc/clang的unused属性,但是我在头文件中使用这些宏来避免在源代码中__attribute__都有gcc特定属性,并且在所有地方都有点冗长/丑陋.

#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
Run Code Online (Sandbox Code Playgroud)

然后你可以......

void foo(int UNUSED(bar)) { ... }
Run Code Online (Sandbox Code Playgroud)

我更喜欢这个,因为如果你尝试bar在任何地方使用代码就会出现错误,所以你不能错误地保留属性.

和功能......

static void UNUSED_FUNCTION(foo)(int bar) { ... }
Run Code Online (Sandbox Code Playgroud)

注1):
据我所知,MSVC没有相应的__attribute__((__unused__)).

注2):
UNUSED宏将不包含括号参数工作,
所以如果你有一个参数一样float (*coords)[3] ,你不能做,
float UNUSED((*coords)[3])或者float (*UNUSED(coords))[3],这是唯一的缺点UNUSED我迄今发现的宏,在这些情况下,我回落至(void)coords;


Ted*_*ddy 18

使用带有未使用属性的gcc:

int foo (__attribute__((unused)) int bar) {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


kei*_*ith 14

从 C++ 17 开始,该[[maybe_unused]]属性可用于抑制有关未使用参数的警告。

基于OP的示例代码:

Bool NullFunc([[maybe_unused]] const struct timespec *when, [[maybe_unused]] const char *who)
{
   return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,问题指定的是 C 而不是 C++。这个答案在 C++ 中可以很好地工作。对于任何想用普通的旧 C 语言尝试这个的人来说,它会在没有警告的情况下进行编译(至少使用 GCC),因此它“有效”,但像 clang-tidy 这样的工具会讨厌它。 (2认同)

Pau*_*son 10

看到这被标记为gcc,您可以使用命令行开关Wno-unused-parameter.

例如:

gcc -Wno-unused-parameter test.c
Run Code Online (Sandbox Code Playgroud)

当然,这会影响整个文件(可能会根据您设置开关的位置进行投影),但您不必更改任何代码.


小智 5

标记属性是理想的方式.MACRO导致有时混乱.并且通过使用void(x),我们在处理中增加了开销.

如果不使用输入参数,请使用

void foo(int __attribute__((unused))key)
{
}
Run Code Online (Sandbox Code Playgroud)

如果不使用函数内定义的变量

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

   api_call(x, hash, bkt);
}
Run Code Online (Sandbox Code Playgroud)

现在稍后使用哈希变量为您的逻辑,但不需要bkt.将bkt定义为未使用,否则编译器说'bkt set bt not used".

注意:这只是为了抑制警告而不是优化.

  • 使用 `void(x)` 不会在处理过程中增加任何开销,编译器会优化它。 (2认同)

lan*_*ung 5

我遇到了同样的问题。我使用了第三方库。当我编译这个库时,编译器 (gcc/clang) 会抱怨未使用的变量。

像这样

test.cpp:29:11: 警告:变量 'magic' 设置但未使用 [-Wunused-but-set-variable] short magic[] = {

test.cpp:84:17: 警告:未使用的变量 'before_write' [-Wunused-variable] int64_t before_write = Thread::currentTimeMillis();

所以解决方案很明确。添加-Wno-unused为 gcc/clang CFLAG 将抑制所有“未使用”警告,即使您已-Wall设置。

这样,您无需更改任何代码。

  • 如果您真的想忽略所有未使用的警告,这很好,但几乎从来没有这种情况。它通常只是您想要忽略的特定实例。 (2认同)

小智 5

抑制源代码块的未使用参数警告的gcc/g ++特定方法是使用以下pragma语句将其括起来:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
<code with unused parameters here>
#pragma GCC diagnostic pop
Run Code Online (Sandbox Code Playgroud)


use*_*610 5

告诉您的编译器使用编译器特定的非标准机制

__attribute__((unused))请参阅、各种#pragmas 等的单独答案。(可选)将预处理器宏包裹在其周围以实现可移植性。

关闭警告

IDE 可以直观地指示未使用的变量(不同颜色或下划线)。有了这个,编译器警告可能就毫无用处了。

在 GCC 和 Clang 中,-Wno-unused-parameter在命令行末尾添加选项(在所有打开未使用参数警告的选项之后,例如-Wall, -Wextra)。

添加强制类型转换为 void

void foo(int bar) {
    (void)bar;
}
Run Code Online (Sandbox Code Playgroud)

根据jamesdlin 的回答Mailbag: Shutting up compiler warnings

不要给变量命名(仅限 C23 和 C++)

在 C23 标准之前的 C 中不允许这样做,但使用最新的编译器(2023 年)和 C++ 中(从那时起就像永远)可以做到

void foo(int /*bar*/) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

请参阅N2480 在函数定义中允许未命名参数 (pdf)提案,并在https://en.cppreference.com/w/c/compiler_support检查实施状态。

GCC 11、Clang 11 和 ICX 2022.2 (oneAPI 2022.3) 支持此功能。

使用标准属性(C23、C++17)

在C++17中,有一个[[maybe_unused]]属性已成为标准的一部分。在此之前,还有[[gnu::unused]]。请参阅clang 文档以获取更多概述。(gnu::一般来说,这些属性也适用于 clang。)

作为 C 标准化工作的一部分,使 C 和 C++ 功能更加紧密地结合在一起,在 C23 中,我们获得了C 语言的新属性。其中之一[[maybe_unused]]与 C++ 版本的工作方式相同。编译[[gnu::unused]]器特定的属性在 C23 之前的版本中不可用,因为早期的 C 语言版本根本没有这些属性。