鉴于存在危险,为什么项目要使用-I include开关? [英] Why do projects use the -I include switch given the dangers?

查看:183
本文介绍了鉴于存在危险,为什么项目要使用-I include开关?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读了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 -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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆