阅读细则-I
在 GCC 中切换时,我相当震惊地发现在命令行上使用它会覆盖系统包含。来自预处理器文档 https://gcc.gnu.org/onlinedocs/cpp/Invocation.html#Invocation
“您可以使用-I
覆盖系统头文件,替换您自己的版本,因为这些目录是在标准系统头文件目录之前搜索的。”
他们看起来并没有说谎。在两个具有 GCC 7 的不同 Ubuntu 系统上,如果我创建一个文件endian.h
:
#error "This endian.h shouldn't be included"
...然后在同一目录中创建一个main.cpp
(或main.c,相同的区别):
#include <stdlib.h>
int main() {}
然后编译g++ main.cpp -I. -o main
(或 clang,相同的区别)给我:
In file included from /usr/include/x86_64-linux-gnu/sys/types.h:194:0,
from /usr/include/stdlib.h:394,
from /usr/include/c++/7/cstdlib:75,
from /usr/include/c++/7/stdlib.h:36,
from main.cpp:1:
./endian.h:1:2: error: #error "This endian.h shouldn't be included"
所以 stdlib.h 包含这个 types.h 文件,第 194 行只是说#include <endian.h>
。我明显的误解(也许是其他人的误解)是尖括号会阻止这种情况,但是 -I 比我想象的要强。
虽然不强enough,因为您甚至无法通过首先在命令行上粘贴 /usr/include 来修复它,因为:
“如果标准系统包含目录,或者用-isystem
,也指定为-I
, the -I
选项被忽略。该目录仍会被搜索,但作为系统目录位于系统包含链中的正常位置。”
事实上,详细输出为g++ -v main.cpp -I/usr/include -I. -o main
将 /usr/include 留在列表底部:
#include "..." search starts here:
#include <...> search starts here:
.
/usr/include/c++/7
/usr/include/x86_64-linux-gnu/c++/7
/usr/include/c++/7/backward
/usr/lib/gcc/x86_64-linux-gnu/7/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
让我感到惊讶。我想提出这个问题:
大多数项目使用的合法理由是什么-I
考虑这个极其严重的问题?您可以根据偶然的名称冲突覆盖系统上的任意标头。不应该几乎每个人都在使用-iquote
反而?