Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

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

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" 

...and then in the same directory create a main.cpp (or main.c, same difference):

#include <stdlib.h> int 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" 

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.

Though not strong enough, because you can't even fix it by sticking /usr/include in on the command line first, because:

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

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:

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?

like image 480
HostileFork says dont trust SE Avatar asked Nov 05 '18 12:11

HostileFork says dont trust SE


People also ask

What are the threats of using project management systems in IT projects?

The top two threats in project management today are that a project will not be completed on time or will be completed at a higher-than-expected cost. Learning to face these threats can increase your success as a project manager, an entrepreneur or even an individual contributor.

What are the 3 most general categories of risks to a project?

Project risk is the potential of a project to fail. There are three main types of project risks: cost, schedule, and performance.

What are the 5 common project hazards?

Five always-risky activities are presented—integration, data migration, customization, unproven technology/team, and too-large project.


1 Answers

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

like image 134
PSkocik Avatar answered Sep 24 '22 22:09

PSkocik