gcc 警告:已使用但未定义的函数

Posted

技术标签:

【中文标题】gcc 警告:已使用但未定义的函数【英文标题】:gcc warning: function used but not defined 【发布时间】:2011-04-02 22:59:00 【问题描述】:

我收到警告:function used but not defined。我在头文件中有static __inline__a.h。头文件包含在a.c 中。我想将头文件中的所有内联函数放入.c 文件中。以下代码给出了我的问题的想法。

原始代码:

啊哈:

static __inline__ function1()
    function definition;  

我变了: 啊:

static function1();

交流:

#include "a.h"

static function1()
   function definition;

在执行上述操作时,我收到了警告:

   warning: function function1 is used but not defined. 

你能告诉我为什么我会收到这样的警告吗?我想将所有__inline__ 函数转移到.c 中,这样我就不会收到警告:

  warning: function1 is could not be inlined, code size may grow.

提前致谢

【问题讨论】:

请修正您代码中的代码格式;真是一团糟! 请记住为每个函数提供返回类型 - 您使用的是 C99,而 C99 需要它。 【参考方案1】:

您已将函数声明为静态。这意味着它仅在当前编译单元中可见。换句话说:实现只在a.c 文件中可见。您需要删除a.ha.c 中的static 关键字,以便其他.c 文件可以看到该功能。您应该指定一个返回值,例如void function1();,因为如果您没有指定,它隐含地是 int

【讨论】:

【参考方案2】:

.c 文件中声明的函数 static 仅在该文件中可见/可用。如果它们没有在其中使用,那么它们实际上是死代码,编译器会警告你这个事实。在 GCC 中,您可以使用 unused function attribute 来抑制此警告:

static int __attribute__((unused)) function1() 
...

编辑:

一般而言,您通常应遵循以下有关内联函数的准则:

如果它们在多个 C 文件中使用,请将它们声明为 static 并将它们的定义放在包含的头文件中。这允许所有包含该头文件的.c 文件拥有自己的函数private 定义,从而允许编译器内联它。单独的 static 函数 prototypes 在将由多个源文件使用的头文件中几乎没有意义,因为它们的实际定义将丢失。

如果它们不打算重复使用,请将它们的定义(以及,如果必要的话,它们的原型)放在应该使用它们的 .c 文件中。

如果 GCC 抱怨由于函数大小而无法内联函数:

问问自己是否真的需要内联该函数 - 根据我的经验,编译器通常最清楚。

如果您真的非常想内联该函数,always_inline function attribute 可能会很有用。您可能还必须为 GCC 提供一个非默认的 -finline-limit=n 选项以增加内联函数的允许大小。

另请参阅this,了解有关内联函数的更多信息以及关于它们的使用可能存在的一些陷阱。

编辑 2:

如果您在共享头文件中定义了static inline 函数,并且想将其转换为普通函数,由于没有更好的词,您应该:

选择一个 .c 文件,其中该函数的存在是有意义的(即将它与其他相关函数放在一起)。

从其定义中删除 staticinline 关键字,并将标题中的定义移动到该文件中。

staticinline关键字从其原型中去掉,放到头文件中。

恭喜,您现在拥有一个正常的公开功能。

免责声明:您刚刚创建了一个对许多文件是私有的函数,对您的所有程序都是公共的。如果有另一个公共符号 - 变量或函数 - 具有相同的名称,您可能会在链接时遇到错误,甚至在运行时出现奇怪的行为。您已被警告...

【讨论】:

感谢您的描述性回答。实际上我不想内联该功能。所以保持功能不变,我想删除 inline。由于我在 C 文件中定义了特定的内联函数,因此函数前面的关键字 static 是否会造成问题?> static 在函数定义中使该函数 private 仅对该 .c 文件。如果该函数实际上并未在该 .c 文件中使用,则它是死代码,这就是编译器抱怨的原因。【参考方案3】:

在头文件中正常声明函数

啊。

#ifndef A_H_INCLUDED
#define A_H_INCLUDED

void function1(void);

#endif

在没有static的单个代码文件中定义函数

交流

#include "a.h"

void function1(void) 
  /* function definition */

并在包含头文件后从其他文件调用该函数

b.c

#include "a.h"

void quux(void) 
  function1(); /* call regular function */


您以前的方式(static 和头文件中的实现)之所以有效,是因为包含该头文件的每个代码文件都有自己的函数版本;与所有其他文件中的所有其他同名函数不同(但执行完全相同)。

【讨论】:

你的意思是我不应该将函数原型保存在头文件本身中吗?特定的头文件也包含在不同的 C 文件中。或者是关键字 static 造成了差异? 头文件是为了帮助其他文件(翻译单元)知道调用函数的正确方法。如果该函数仅适用于单个 .c 文件(static),则将原型添加到 .h 文件是没有意义的。 我只想删除关键字 inline 保持代码的功能与以前相同。在这种情况下你有什么建议?那些内联函数也在其他C文件中被调用,这种情况下不需要在头文件中定义吗? 那你不能声明函数static。将原型保存在一个头文件(a.h)中,将定义保存在一个代码文件(a.c)中,#include "a.h" 保存在其他代码文件中。

以上是关于gcc 警告:已使用但未定义的函数的主要内容,如果未能解决你的问题,请参考以下文章

Swagger 文件安全方案已定义但未使用

GCC 常用编译选项

“已超出最大错误数”但未列出错误或警告

UIStoryboard 中的自定义原型单元已创建,但未显示在 UITableView

使用编译器/链接器进行 C++ 代码清理

MapBox GL Android:来自自定义图块源的离线地图已下载但未使用