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

后端 未结 4 904
独厮守ぢ
独厮守ぢ 2021-02-01 15:20

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

相关标签:
4条回答
  • 2021-02-01 15:40

    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.

    0 讨论(0)
  • 2021-02-01 15:41

    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.

    0 讨论(0)
  • 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).

    0 讨论(0)
  • 2021-02-01 15:43

    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.

    0 讨论(0)
提交回复
热议问题