正如标题所述,当我包含一些头文件时,我希望我的编译器失败;例如,<cmath>
仅使用编译器标志可能吗?还是我必须实际删除这些标题?
简单地使用预处理器符号来省略库头文件怎么样?-DDONT_WANT_LIBS
由于库头文件中缺少库声明,使用 gcc 选项编译将失败。
#ifndef DONT_WANT_LIBS
#include<specific_library_header.h>
#endif
...
...
#include <cmath>
与任何库无关,与头文件有关。假设您确实意味着如果您包含特定的头文件,您希望编译失败,您应该能够利用GCC 对通过 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'"
确保该文件也可供所有人读取并归根用户所有。#error和它的邪恶双胞胎 #warning 分别发出一个致命错误和一个编译警告,所以每当包含这个文件时,GCC 都会遇到一个 #error 预处理器指令,导致发出一个导致编译失败的致命错误。
如果您想为单个编译覆盖此行为,只需使用 gcc 的-I
参数来指定真正的 math.h 所在目录的路径。由于-I
优先$C_INCLUDE_PATH
,$CPLUS_INCLUDE_PATH
这意味着您随后包含 C 库的版本。例如,无论 /usr/local/include/fail 中可能有什么,cc -o mathprogram -I/usr/include mathprogram.c
都将使用 /usr/include 中的 math.h ,因为它首先在 /usr/include 中查找。#include <math.h>
由于这只影响编译(并且仅通过 shell 启动编译),因此系统上已经存在的所有内容都将完全不受影响(除非它们对这两个环境变量有一些奇怪的依赖关系)。
对于c*
标头,您可能还需要创建*.h
内容与标头相同的相应标c*
头。这是因为 egcmath
可能只是映射到math.h
(C 中相同标头的名称)。只需像上面那样制作另一个文件,但要抱怨math.h
。(GCC 不在乎,但它使诊断更容易。)您可能还需要将文件放在其他地方(我不确定 GCC 对 C++ 头文件到底需要什么包含目录结构);在这种情况下,find / -name cmath
(或类似的东西)会让您了解您需要在 /usr/local/include/fail 下复制的结构。
请注意,这不会阻止人们简单地将头文件的相关部分复制到他们自己的源代码中;从编译器的角度来看,头文件并没有什么神奇之处。这可能是一个问题,具体取决于您要保护的具体内容。