在 C
中,让您的 .h
文件在相应的 .c
文件中包含外部可见符号的声明是一种惯用模式.这样做的目的是为了支持一种“模块和接口(interface)”思维,例如实现更简洁的结构。
在我正在处理的大型遗留 C 系统中,函数在错误的头文件中声明的情况并不少见,可能是在将函数移动到另一个模块之后,因为它仍然可以编译、链接和运行,但这使得模块在他们的界面中不太明确,并指出错误的依赖关系。
有没有办法验证/确认/保证 .h
文件具有来自 .c
的所有外部符号,并且没有不存在的外部符号?
例如如果我有以下文件
module.c
int func1(void) {}
bool func2(int c) {}
static int func3(void) {}
module.h
extern int func1(void);
extern bool func4(char *v);
我想指出的是,func4
不是 module.c
中的外部可见符号,并且缺少 func2
。
现代编译器提供了一些帮助,以至于它们可以检测到您实际引用的缺失声明,但它并不关心它来自哪个文件。
除了手动检查每一对之外,我还有哪些选择可以获取此信息?
最佳答案
I want to be pointed to the fact that func4 is not an external visible symbol in module.c and that func2 is missing.
将 POSIX-ish linux 与 bash
、diff
和 ctags
结合使用,并给出非常简单的输入文件示例,您可以这样做:
$ #recreate input
$ cat <<EOF >module.c
int func1(void) {}
bool func2(int c) {}
static int func3(void) {}
EOF
$ cat <<EOF >module.h
extern int func1(void);
extern bool func4(char *v);
EOF
$ # helper function for extracting only non-static function declarations
$ f() { ctags -x --c-kinds=fp "$@" | grep -v static | cut -d' ' -f1; }
$ # simply a diff
$ diff <(f module.c) <(f module.h)
2,3c2
< func2
---
> func4
$ diff <(f module.c) <(f module.h) |
> grep '^<\|^>' |
> sed -E 's/> (.*)/I would like to point the fact that \1 is not externally visible symbol/; s/< (.*)/\1 is missing/'
func2 is missing
I would like to point the fact that func4 is not externally visible symbol
如果 static
关键字与引入的函数标识符不在同一行,这将中断,因为 ctags
不会输出它们。所以真正的工作是获取外部可见函数声明的列表。这不是一件容易的事,编写这样的工具留给其他人:)
关于c - 如何将 .h 文件中的外部符号验证为 .c 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60504654/