阻止g ++编译器包含特定的头文件

时间:2013-07-07 07:40:57

标签: g++

正如标题所述,当我包含一些头文件时,我希望我的编译器失败;例如,< cmath>

只有编译器标志才可能吗?或者我是否必须实际删除这些标题?

2 个答案:

答案 0 :(得分:1)

如何简单地使用预处理器符号来省略库头? 由于库头文件中缺少库声明,使用gcc选项-DDONT_WANT_LIBS进行编译将失败。

#ifndef DONT_WANT_LIBS
#include<specific_library_header.h>
#endif
   ...
   ...

答案 1 :(得分:1)

#include <cmath>与任何库无关,而且与头文件有关。如果您包含特定的头文件,假设您确实希望编译失败,那么您应该能够利用GCC's support for specifying include directories through environment variables

为此,请创建或编辑适当的环境文件。例如,如果您在Debian上使用GNU bash,则可以创建文件/etc/profile.d/gcc-include-dirs。 /etc/profile.d中的所有内容都是在启动shell时获取的,因此它将应用于该点之后启动的所有shell。 (绝对肯定,您可能需要注销并重新登录一次,然后发出env | grep INCLUDE进行确认。)使用您喜欢的编辑器创建这样的文件并添加以下内容:

export C_INCLUDE_PATH=/usr/local/include/fail:${C_INCLUDE_PATH}
export CPLUS_INCLUDE_PATH=/usr/local/include/fail:${CPLUS_INCLUDE_PATH}

确保所有人(chmod 644 /etc/profile/gcc-include-dirs)都可以读取该文件,并确保该文件归root用户所有(chown root:root /etc/profile/gcc-include-dirs)。

如果您在特定时间只需要此行为,您也可以将文件放在其他地方,并在需要时简单地source。在这种情况下,从有问题的shell中注销并重新登录将恢复GCC的正常行为(您不需要从整个会话中注销,只需注销该特定的shell实例)。从那个子shell开始子shell并从中获取文件在这种情况下也可以很好地工作;完成时只需exit

然后使用以下内容创建文件/usr/local/include/fail/cmath

#error "Failing because you included 'cmath'"

确保所有人都可以读取该文件并由root拥有。 #error及其恶双#warning后发射一个致命错误并且汇编警告,分别,所以每当这个文件被包括在内,GCC将遇到导致致命错误的发射一个#ERROR预处理指令这使得编译到失败。

如果要为单个编译覆盖此行为,只需使用gcc的-I参数指定实际math.h所在目录的路径。由于-I优先于$C_INCLUDE_PATH$CPLUS_INCLUDE_PATH,因此这意味着您可以包含C库的版本。例如,cc -o mathprogram -I/usr/include mathprogram.c将在#include <math.h>中使用math.h,而不管/ usr / local / include / fail中的内容是什么,因为它首先在/ usr / include中查找

由于这只会影响编译(并且只通过shell启动编译),系统中已有的所有内容都将完全不受影响(除非它们对这两个环境变量有一些奇怪的依赖)。

对于c*标头,您可能还需要创建相应的*.h标头,其内容与c*标头相同。这是因为例如cmath可能只是映射到math.h(C中相同标题的名称)。只需像上面那样制作另一个文件,但是抱怨math.h。 (GCC并不关心,但它使诊断更容易。)您可能还需要将文件放在其他地方(我不确定GCC想要的C ++头文件的目录结构);在这种情况下,find / -name cmath(或类似的东西)将让您了解在/ usr / local / include / fail下需要复制的结构。

请注意,这不会阻止人们只是将头文件的相关部分复制到他们自己的源代码中;从编译器的角度来看,没有任何关于头文件的神奇之处。根据您要保护的确切内容,这可能是一个问题。