使用GCC强制显式(直接)#include语句

时间:2013-09-30 18:51:28

标签: c++ c gcc compiler-errors compiler-warnings

我想知道是否可以通过GCC强制执行直接#include要求。假设我有这些文件:

abc.h:

typedef struct {
   int useful;
} str;

file1.h:

#include <abc.h>
#ifndef GUARD
#define GUARD

#include <deh.h>

typedef struct {
   int useful;
} str2;

#endif

file2.h:

#ifndef GUARD2
#define GUARD2
#include <file1.h>

void a_function (str*  my_str);
void a_function2(str2* my_str);

#endif

问题是“file2.h”使用“abc.h”中定义的“str”。假设某些Linux系统上的系统提供了“file1.h”。我无法控制“file1.h”内容。如果可能包括也可能不包括,内部可能包括也可能不包括警卫,并且可能会或可能不会随着时间而改变。

问题在于它支持多个发行版和系统。如果file2.h意外地使用“str”而不包括,它可能在大多数系统上都可以编译,但在其他系统上可能会失败,或者将来“file1.h”更改时会失败。

有没有办法强制GCC(或LLVM)只使用file2.h中直接定义的类型?我理解“#include”只是那个,包括,因此编译器内部可能在预处理器阶段之后不会意识到这些问题,但是,我想知道这是否可能,如果可能的话,怎么样?

我使用“普通”Linux发行版时遇到过这个问题,但是早期的Android NDK版本更糟糕。

2 个答案:

答案 0 :(得分:2)

不,#include指示编译器将其他文件的内容视为放在#include指令中 - 您要求以不同方式处理其他文件的内容。< / p>

在这种情况下,您最好的希望是使用静态分析工具执行依赖关系分析,并检查通过间接(嵌套)包含获得的类型(或函数或对象)没有直接依赖关系。

免费doxygen文档工具提取有关包含和依赖关系的信息,它以XML格式提供。当然,就重载分辨率和模板处理而言,它不如真正的编译器那么准确。我确信有些付费工具会更准确(用户Ira Baxter不时会提到他公司销售的商业产品,DMS Toolkit或类似的东西,这听起来像是可以获得这些信息)。但我猜测doxygen会为大多数“普通”代码提供正确的结果。

答案 1 :(得分:1)

C ++语言中没有任何内容可以验证是否正确包含了所有标头。但是,include-what-you-use基于clang。我没有尝试过使用它,但它似乎正朝着你所寻找的方向发展。对于C,实现分析器检测依赖关系并报告缺少直接包含似乎是相当直接的。在使用C ++进行相同操作时,由于需要检测模板实例化的依赖性,因此事情会变得更加困难。

根据上周在C ++委员会会议上的讨论,重构源代码和标题以正确包含实际使用的内容可能对C ++中的未来module support有所帮助。