2010-08-30 84 views
156

在C代码中抑制未使用的参数警告的最佳方法是什么?“未使用的参数”警告C

例如,

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

在C++中,我能够把/*...*/评论周围的参数。但当然不是。

它给我error: parameter name omitted

+0

可能的重复[什么是最好的方法来抑制“未使用变量x” - 警告](http://stackoverflow.com/questions/3417837/what-is-the-best-way-to-supress-unused -variable-x-warning) – 2014-09-17 07:14:04

+3

@CiroSantilli这个问题有更多upvotes,最好将其他问题标记为重复。 – sashoalm 2015-01-20 13:18:42

+1

另请参见[此问题的C++版本](http://stackoverflow.com/q/1486904/1708801) – 2015-07-28 19:58:34

回答

227

我平时写这样一个宏:

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

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

例如:

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

我只是使用(void)x直接 – 2012-05-30 11:27:17

+0

+1。最后一个便携式解决方案。 – Jack 2012-11-07 02:24:18

+5

虽然这是AFAIK的唯一便携式方式,但如果稍后使用该变量,则可能会引起误解,并忘记ro删除未使用的行。这就是为什么GCC的__unused__很好。 – ideasman42 2012-11-07 13:58:58

73

在海湾合作委员会,你可以标记与unused attribute参数。

该属性,连接到一个变量,表示该变量是 意味着是可能未使用。 GCC不会为此 变量产生警告。

实际上,这是通过在参数后面加上__attribute__ ((unused))来实现的。例如

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

成为

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

对于像我这样的新手来说,这意味着将'__attribute__((未使用))'放在参数前面。 – josch 2014-09-19 05:53:31

+1

@josch我认为你是完全正确的,但文档似乎暗示它应该放在参数后面*。这两个选项都可能支持没有问题。 – Antonio 2015-04-24 09:43:06

2

我已经看到了这种风格beeing使用:

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

嗯。我不能说我喜欢这个,因为这里假定所有涉及的参数都可以转换成布尔值。 – Suma 2011-12-21 07:05:07

+0

这并不是一个很好的约定,尽管编译器几乎可以肯定会优化它,但它不太清楚会发生什么情况,并可能会混淆静态源代码检查器。在这里恕我直言,更好地使用其他建议之一。 – ideasman42 2012-10-31 04:08:03

+1

我不相信我仍然得到这个答复。这个问题表明这是针对C的。是的,在另一种语言中这是行不通的。 – Iustin 2013-03-17 14:11:52

51

您可以使用gcc /铛未使用的属性,但是我在标题中使用这些宏为了避免在源代码中使用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 

然后你就可以做...

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;

+0

或者可能只是'#define __attribute __(x)'为非GCC环境(AFAIK MSVC不支持__attribute__')? – 2017-11-10 06:16:49

+0

这可以工作,但dunder的前缀是为编译器保留的,所以我宁愿避免这种情况。 – ideasman42 2017-11-10 11:22:10

+0

对于我的gcc,至少在标识符似乎适用于funcs,vars和参数之前放置属性说明符,所以类似#define POSSIBLY_UNUSED(identifier)__attribute __((__ unused__))标识符可用于所有三个 – 2018-03-02 22:01:36

0

为了记录在案,我喜欢工作的回答以上,但我很好奇的解决方案只是一个使用变量名本身“无所事事“的状态nt:

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

当然,这有缺点;例如,没有“未使用”的注释,它看起来像是一个错误,而不是有意识的代码行。

好处是,不需要DEFINE,它可以摆脱警告。

是否有任何性能,优化或其他差异?

+2

我用这与MSVC,但GCC引发“声明无效”警告。所以,Job的解决方案就是要走的路。 – 2013-05-14 06:32:21

14

与未使用的属性GCC:

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

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

如果不使用输入参数,如果不使用该功能

​​

内定义的变量现在在以后使用散列变量为你的逻辑,但并不需要BKT使用

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

。定义BKT为未使用,否则编译器says'bkt设置BT不使用”

注意:这只是相应的警告不是优化

2

我得到了同样的问题,我用第三件库当我编译这个库,编译器(GCC /铛)会抱怨未使用的变量

像这样

TEST.CPP:29:11:警告:变“魔术”设置,但不使用[-Wunused-but-set-variable] short magic [] = {

test.cpp:84:17:warning:unused variable'before_write'[-Wunused-variable] int64_t before_write = Thread :: currentTimeMillis();

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

通过这种方式,您不需要更改任何代码。

+1

这很好,如果你真的想忽略所有未使用的警告,但几乎从来没有这样。它通常只是您想忽略的特定实例。 – Dan 2016-11-05 18:07:31

4

一个gcc /克++抑制为源代码中的块中的未使用的参数的警告特定的方式与如下pragma语句它括:

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

Clang支持这些诊断编译以及https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas – eush77 2017-04-28 15:49:28

+0

优秀的答案。非常感谢。 – pylover 2018-01-28 12:00:19

0

在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三年,但他们压制不会影响结果的超级警告。