鉴于存在危险,为什么项目要使用-I include开关? [英] Why do projects use the -I include switch given the dangers?
问题描述
阅读了GCC中 -I
开关的详细信息后,我很震惊地发现在命令行上使用它会覆盖系统包含的内容。从预处理器文档
Reading the fine print of the -I
switch in GCC, I'm rather shocked to find that using it on the command line overrides system includes. From the preprocessor docs
您可以使用
-I
覆盖系统头文件,替换您自己的版本,因为已搜索这些目录在标准系统头文件目录之前。
"You can use
-I
to override a system header file, substituting your own version, since these directories are searched before the standard system header file directories."
它们似乎不是在撒谎。在带有GCC 7的两个不同的Ubuntu系统上,如果我创建文件 endian.h
:
They don't seem to be lying. On two different Ubuntu systems with GCC 7, if I create a file endian.h
:
#error "This endian.h shouldn't be included"
...然后在同一目录中创建 main.cpp
(或main.c,相同的区别):
...and then in the same directory create a main.cpp
(or main.c, same difference):
#include <stdlib.h>
int main() {}
然后使用 g ++ main进行编译.cpp -I。 -o main
(或叮当声,相同的区别)给我:
Then compiling with g++ main.cpp -I. -o main
(or clang, same difference) gives me:
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包括此类型。 h文件,该文件在第194行仅显示 #include< endian.h>
。我明显的误解(也许还有其他人的误解)是尖括号会阻止这种情况,但是-我比我想象的要强。
So stdlib.h includes this types.h file, which on line 194 just says #include <endian.h>
. My apparent misconception (and perhaps that of others) was that the angle brackets would have prevented this, but -I is stronger than I'd thought.
尽管不牢固足够,因为您甚至无法通过首先在命令行上粘贴/ usr / include来解决它,因为:
Though not strong enough, because you can't even fix it by sticking /usr/include in on the command line first, because:
如果标准系统包含目录,或者使用
-isystem
指定的目录,也使用-I $指定c $ c>,
-I
选项将被忽略。该目录仍在搜索,但作为系统目录在系统包含链中的正常位置。
"If a standard system include directory, or a directory specified with
-isystem
, is also specified with-I
, the-I
option is ignored. The directory is still searched but as a system directory at its normal position in the system include chain."
实际上是 g ++ -v main.cpp -I / usr / include -I的详细输出。 -o main
将/ usr / include留在列表的底部:
Indeed, the verbose output for g++ -v main.cpp -I/usr/include -I. -o main
leaves /usr/include at the bottom of the list:
#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
让我惊讶。我想让这个问题成为问题:
Color me surprised. I guess to make this a question:
大多数项目使用 -I
考虑到这个极其严重的问题?您可以基于偶然的名称冲突在系统上覆盖任意标头。不是每个人都应该使用 -iquote
代替吗?
What legitimate reason is there for most projects to use -I
considering this extremely serious issue? You can override arbitrary headers on systems based on incidental name collisions. Shouldn't pretty much everyone be using -iquote
instead?
推荐答案
-I
超过 -iquote
有什么正当理由? -I
是标准化的(至少由 POSIX ),而 -iquote
不是。 (实际上,我使用的是 -I
,因为tinycc(我希望我的项目与之编译的编译器之一)不支持 -iquote
。)
What legitimate reasons are there for -I
over -iquote
? -I
is standardized (at least by POSIX) while -iquote
isn't. (Practically, I'm using -I
because tinycc (one of the compilers I want my project to compile with) doesn't support -iquote
.)
在存在危险的情况下,如何使用 -I
管理项目?您将把include包裹在一个目录中,并使用-I添加包含该目录的目录。
How do projects manage with -I
given the dangers? You'd have the includes wrapped in a directory and use -I to add the directory containing that directory.
- 文件系统:
includes / mylib / endian.h
- 命令行:
-Iincludes
- C / C ++文件:
#include mylib / endian.h //或< mylib / endian.h>
- filesystem:
includes/mylib/endian.h
- command line:
-Iincludes
- C/C++ file:
#include "mylib/endian.h" //or <mylib/endian.h>
有了这个,只要您不冲突 mylib
名称,您就不会冲突(至少就标题名称而言)。
With that, as long as you don't clash on the mylib
name, you don't clash (at least as far header names are concerned).
这篇关于鉴于存在危险,为什么项目要使用-I include开关?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!