c - 如何将 .h 文件中的外部符号验证为 .c 文件?
问题描述
C
让您的文件包含相应文件中外部可见符号的声明是一种惯用.h
模式.c
。这样做的目的是为了支持一种“模块和接口”思维,例如启用更简洁的结构。
在我正在研究的大型遗留 C 系统中,可能在将函数移动到另一个模块之后,在错误的头文件中声明函数并不少见,因为它仍然可以编译、链接和运行,但这使得模块在它们的接口并指示错误的依赖关系。
有没有办法验证/确认/保证.h
文件包含所有外部符号,.c
并且没有外部符号不存在?
例如,如果我有以下文件
模块.c
int func1(void) {}
bool func2(int c) {}
static int func3(void) {}
模块.h
extern int func1(void);
extern bool func4(char *v);
我想指出这样一个事实,即func4
它不是外部可见符号module.c
并且func2
缺失了。
现代编译器提供了一些帮助,它们可以检测到您实际引用的缺失声明,但它并不关心它来自哪个文件。
除了手动检查每一对之外,我还有哪些选择来获取此信息?
解决方案
我想指出 func4 不是 module.c 中的外部可见符号并且缺少 func2 的事实。
使用 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
不会输出它们。所以真正的工作是获取外部可见的函数声明列表。这不是一件容易的事,编写这样的工具留给其他人:)
推荐阅读
- python - Python 'getopt' 语法,允许可选的命令行参数,longopts 无法识别
- python - to_csv 将每个插入数据的列标签存储到 csv 文件
- python - python pandas数据框错位
- rust - 无法指定生命周期参数来解决编译错误
- java - 无法将 protobuf 消息类型转换为镶木地板
- c++ - 当相机远离屏幕时,glDrawArraysInstanced 的行为很奇怪
- mysql - mysql远程连接digitalocean
- python - 将 QWidgets 堆叠在一起,两者都可见
- php - 通过从每个数组中一次提取 3 个元素将两个数组合并为一个平面数组
- ios - Swift - 从实时摄像机中获取静止帧并将它们输入 Vision 框架