检测C头文件中的未定义符号

时间:2010-12-20 15:27:28

标签: c compiler-construction libraries

Suposse我编写了一个C库,它提供了一堆“公共”函数,在mylib.h头文件中声明。这些函数应该在(例如)mylib.c文件中实现,该文件被编译为(例如)静态库mylib.c -> mylib.o -> mylib.a

有没有办法检测到我忘了在mylib.h中提供某些声明函数的实现? (是的,我知道单元测试,良好实践等等 - 是的,我理解C中普通函数声明的含义。)

假设mylib.h声明了void func1();,并且此函数未在提供的库中编码。仅当链接器需要使用该功能时,才会触发错误。否则,它将编译好,甚至没有警告 - AFAIK。有没有办法(可能是编译器相关的)触发已声明但未实现的函数的警告,还是有其他方法来处理这个问题?

BTW:nm -u不是列出所有未定义的声明函数,而是列出库中“使用”的那些函数,即那些在链接阶段触发错误的函数(如果没有在某处声明)。 (当然,有意义的是,库对象文件不知道头文件。)

4 个答案:

答案 0 :(得分:2)

没有简单的方法。

例如,您可以分析clang -Xclang -ast-print-xmlgcc-xml的输出,并过滤掉没有针对给定.h文件的实现的声明。

答案 1 :(得分:2)

基本上,最可靠的方法是拥有一个程序(或可能是一系列程序),正式执行每个功能。如果其中一个程序由于缺少符号而无法链接,那么你就会蠢蠢欲动。

我想你可以尝试通过将头文件的副本编辑成源文件(如文件结尾.c)来做某事,将函数声明转换为虚函数定义:

原件:

extern int somefunc(void);

修:

extern int somefunc(void){}

然后使用最小警告编译修改后的源 - 并忽略与“应该返回值的函数不相关的任何事情”。然后将修改后的源文件中的已定义符号与库中定义的符号进行比较(在类Unix系统上使用nm -g)。

中缺少目标文件中存在的库中不存在的任何内容。

注意:如果您的标题包含您自己定义函数的其他标题,则需要处理所有这些标题。如果您的标题包含标准标题,例如<stdio.h>,那么显然您不会在正常的事件过程中定义fopen()printf()等函数。因此,请仔细选择您重新处理为源代码的标题。

答案 2 :(得分:0)

您可以在.h和.c中查找导出函数的签名,并比较列表。 使用wc -l计算匹配,两个数字应该相等。

另一个想法,刚出现在我的脑海里。使用编译器是不可能处理它的ihmo。情况并非总是如此,mylib.h中的函数声明是在mylib.c中实现的

答案 3 :(得分:0)

  

有没有办法检测到我忘了在mylib.h中提供某些声明函数的实现?

首先编写实现,然后担心标题内容 - 因为这样,它可以被标记。