Why do projects use the -I include switch given the dangers?

醉酒当歌 提交于 2019-12-02 18:52:09

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.)

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.

  • filesystem: includes/mylib/endian.h
  • command line: -Iincludes
  • C/C++ file: #include "mylib/endian.h" //or <mylib/endian.h>

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).

Looking back at the GCC manuals it looks like -iquote and other options were only added in GCC 4: https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Directory-Options.html#Directory%20Options

So the use of "-I" is probably some combination of: habit, lazyness, backwards compatibility, ignorance of the new options, compatibility with other compilers.

The solution is to "namespace" your header files by putting them in sub directories. For example put your endian header in "include/mylib/endian.h" then add "-Iinclude" to the command line and you can #include "mylib/endian.h" which shouldn't conflict with other libraries or system libraries.

I this your premise that it's -I that's dangerous is false. The language leaves the search for header files with either form of #include sufficiently implementation-defined that it's unsafe to use header files that conflict with the names of the standard header files at all. Simply refrain from doing this.

An obvious case is cross-compilation. GCC suffers a bit from a historical UNIX assumption that you're always compiling for your local system, or at least something that's very close. That's why the compiler's header files are in the system root. The clean interface is missing.

In comparison, Windows assumes no compiler, and Windows compilers do not assume you're targeting the local system. That's why you can have a set of compilers and a set of SDK's installed.

Now in cross-compilation, GCC behaves much more like a compiler for Windows. It no longer assumes that you intend to use the local system headers, but lets you specify exactly which headers you want. And obviously, the same then goes for the libraries you link in.

Now note that when you do this, the set of replacement headers is designed to go on top of the base system. You can leave out headers in the replacement set if their implementation would be identical. E.g. chances are that <complex.h> is the same. There's not that much variation in complex number implementations. However, you can't randomly replace internal implementation bits like <endian.h>.

TL,DR : this option if for people who know what they're doing. "Being unsafe" is not an argument for the target audience.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!