检测C头文件中未定义的符号
假设我编写了一个 C 库,它提供了一堆“公共”函数,在 mylib.h
头文件中声明。这些函数据说是在(例如)mylib.c 文件中实现的,该文件被编译为(例如)静态 lib mylib.c -> 。 mylib.o-> mylib.a
。
有没有什么方法可以检测到我忘记提供 mylib.h 中某些声明函数的实现? (是的,我了解单元测试、良好实践等 - 并且,是的,我了解 C 中简单函数声明的含义)。
假设 mylib.h 声明了一个 void func1(); 且该函数未在提供的库中进行编码。仅当链接器需要使用该函数时才会触发错误。否则,它会编译正常,甚至没有警告 - AFAIK。有没有一种方法(可能取决于编译器)来触发已声明但未实现的函数的警告,或者有其他方法来处理此问题?
顺便说一句: nm -u 并未列出所有未定义的声明函数,而仅列出了那些被库“使用”,即那些如果未在某处声明的函数将在链接阶段触发错误。 (这是有道理的,当然,库目标文件不知道头文件。)
Suposse I coded a C library which provides a bunch of "public" functions, declared in a mylib.h
header file. Those functions are supposedly implemented in (say) a mylib.c
file which is compiled to a (say) static lib mylib.c -> mylib.o -> mylib.a
.
Is there some way to detect that I forgot to provide the implementation of some declared function in mylib.h
? (Yes, I know about unit testing, good practices, etc - and, yes, I understand the meaning of a plain function declaration in C).
Suppose mylib.h
declares a void func1();
and this function was not coded in the provided library. This will trigger an error only if the linker needs to use that function. Otherwise, it will compile ok and even without warnings - AFAIK. Is there a way (perhaps compiler dependent) to trigger a warning for declared but not implemented functions, or there is any other way to deal with this issue?
BTW: nm -u lists not all undefined declared functions, but only those "used" by the library, i.e., those functions that will trigger an error in the linking phase if not declared somewhere. (Which makes sense, the library object file does not know about header files, of course.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
基本上,最可靠的方法是制定一个程序(或者可能是一系列程序)来正式执行每一项功能。如果其中一个程序由于缺少符号而无法链接,那么您就犯了错误。
我想您可以尝试通过将标头的副本编辑到源文件中(如以
.c
结尾的文件),将函数声明转换为虚拟函数定义来执行某些操作:原始:
修订:
然后用最少的警告编译修改后的源代码 - 并忽略与“应该返回值的函数没有”有关的任何内容。然后将修订后的源文件中的目标文件中定义的符号与库中定义的符号进行比较(在类 Unix 系统上使用
nm -g
)。目标文件中存在但库中不存在的任何内容都会丢失,应提供。注意:如果您的标头包含您自己定义函数的其他标头,则您需要处理所有这些标头。如果您的标头包含标准标头,例如
,那么显然您不会定义诸如fopen()
或printf() 之类的函数
在正常的事件过程中。因此,请仔细选择重新处理为源代码的标头。Basically, the most reliable way is to have a program (or possibly a series of programs) which formally exercise each and every one of the functions. If one of the programs fails to link because of a missing symbol, you've goofed.
I suppose you could try to do something by editing a copy of the header into a source file (as in, file ending
.c
), converting the function declarations into dummy function definitions:Original:
Revised:
Then compile the modified source with minimum warnings - and ignore anything to do with "function that is supposed to return a value doesn't". Then compare the defined symbols in the object file from the revised source with the defined symbols in the library (using
nm -g
on Unix-like systems). Anything present in the object file that isn't present in the library is missing and should be supplied.Note: if your header includes other headers of your own which define functions, you need to process all of those. If your header includes standard headers such as
<stdio.h>
, then clearly you won't be defining functions such asfopen()
orprintf()
in the ordinary course of events. So, choose the headers you reprocess into source code carefully.没有简单的方法。
例如,您可以分析
clang -Xclang -ast-print-xml
或gcc-xml
的输出,并过滤掉给定 .h 文件没有实现的声明。There's no easy way.
For example, you can analyse the output of
clang -Xclang -ast-print-xml
orgcc-xml
and filter out declarations with no implementations for a given .h file.您可以 grep 查找 .h 和 .c 中导出函数的签名,并比较列表。
使用 wc -l 来计算匹配次数,两个数字应该相等。
另一个想法刚刚浮现在我的脑海中。我不可能使用编译器来处理它。情况并非总是如此,在 mylib.h 中声明的函数在 mylib.c 中实现
You could grep for signatures of exported function in both .h and .c, and compare the lists.
Use wc -l for counting matches, Both numbers should be equal.
Another thought, just came to my mind. It is ihmo not possible to handle it using compiler. it is not always the case, that function declares in mylib.h is implemented in mylib.c
首先编写实现,然后担心标头内容——因为这样,它就可以被标记。
Write the implementation first, then worry about header contents -- because that way, it can be flagged.