函数已定义但未在C中使用警告

the*_*tna 31 c warnings

我有许多C源文件(.c和.h文件).头文件包含许多功能.在这些函数中,只有部分用于源.C文件.假设啊,bh是头文件,ac和bc是.c文件.啊是包含在ac但只有一些功能在一个.使用h并且不使用休息.编译后我发现以下警告:

 function XXXX defined but not used.
Run Code Online (Sandbox Code Playgroud)

但是那些未在ac中使用的XXXX函数在bc中使用所以,我也无法完全删除这些函数.因此,我决定创建一个单独的文件,只包含那些XXXX函数,并将其包含在任何使用它的位置.这样做会创建多个头文件.任何人都可以建议我一些有效的方法来解决这个问题.

AnT*_*AnT 70

"函数已定义但未使用"警告仅针对具有内部链接的函数发出,即声明为的函数static.这些函数只能在一个转换单元中访问,因此编译器始终知道它们是否被使用(在程序中).如果您未在其翻译单元中引用这些功能,则已知这些功能未使用,并生成警告.

你说这些函数"不用于交流,但用于bc".这不是真的.当您static在头文件中声明(和定义)函数时,包含该头文件的每个转换单元都会获得其自己的函数内部副本.即使这些功能看起来完全相同,它们仍然是独立的,完全独立的功能.它们具有相同的名称并由相同的代码组成的事实对编译器没有任何意义.所以,b.c你得到了一个完全独立的函数副本(正如你所说的那样),但a.c仍然没有使用完全独立的副本.

在这种情况下,问题是为什么你正在做这个.为什么在地球上你在头文件中定义静态函数?如果你真的需要这样做(即如果你真的想在每个翻译单元中产生这个函数的单独内部"克隆"),你可以通过使用一些特定于编译器的方法来解决警告.例如,在GCC中,您可以声明该函数,__attribute__((unused))并且不再发出此函数的警告.

但通常不需要在头文件中定义函数.通常一个人使用具有外部链接的函数(即没有static),在其中一个.c文件中定义它并将声明(原型)放在头文件中.在这种情况下,编译器不会发出任何警告,即使该函数已声明但未在某些翻译单元中使用.


tho*_*ter 8

如果您只想隐藏警告,请使用:

-Wno-unused-function
Run Code Online (Sandbox Code Playgroud)

但是,您应该遵循caf的答案中的建议.听起来你可能已经定义了一个函数,只是想要添加它的声明.

  • 从我的阅读中,我猜这些警告是非常有效的,不应该被隐藏。我认为 Andrey 和 caf 是正确的,因为 OP 在 .h 文件中定义了静态函数。简单地隐藏这些警告不会有帮助;这很可能会导致更大的问题。 (2认同)

Jon*_*eld 8

作为"不要那样做"的替代方案,请考虑以下内容 - 一组将触发最多三个未使用功能警告的功能.

static int get_version_number(void) { return 42; }
static double hidden_global_variable(void) { return 3.14; }
static int potential_alternative_to_macro(int x) { return 4 * x; } 
Run Code Online (Sandbox Code Playgroud)

编写另一个函数,可能基于头文件的名称,

static void wno_unused_myheadername(void)
{
  /* don't need to actually call the functions to avoid the warnings */
  (void)&get_version_number;
  (void)&hidden_global_variable;
  (void)&potential_alternative_to_macro;
  return;
 }
Run Code Online (Sandbox Code Playgroud)

我们现在只有一个未使用的功能警告.如果在包含标题的文件中声明的任何外部函数中添加对wno_unused_myheadername()的调用,则整组未使用的函数警告将消失.因为他们现在都被使用了.

编译器将从所有未使用的函数中删除所有未使用的函数,包括wno_unused_myheadername,因为它可以看到所有定义,并且可能确定对wno_unused函数的单个调用实际上没有做任何事情.

我已经检查过上面删除了clang和gcc下预期的警告,你的milage可能会因其他编译器而异.我没有查看asm输出来调查何时剥离几乎未使用的函数.

至于为什么 - 一个很好的理由是使用很多小函数,它们非常适合在C89中内联,它没有内联关键字,不需要编译器的链接时间优化.


coo*_*mbe 6

另一种可能性是将这些功能定义为inline代替static.在这种情况下,需要在标题中定义它们,以便定义在调用它们的任何位置都可见.

编译器将在每个使用该函数的地方内联代码,因此请注意这是您真正想要的.这是一个很好的讨论这些权衡的答案.