Читая мелкий шрифт переключателя -I
в GCC, я довольно шокирован, обнаружив, что использование его в командной строке переопределяет систему. Из документов препроцессора
"Вы можете использовать
-I
для переопределения файла системного заголовка, заменив свою собственную версию, так как эти каталоги ищутся перед стандартными каталогами файлов системного заголовка".
Кажется, они не лгут. В двух разных системах Ubuntu с GCC 7, если я создаю файл endian.h
:
#error "This endian.h shouldn't be included"
... а затем в том же каталоге создайте main.cpp
(или main.c, с той же разницей):
#include <stdlib.h>
int main() {}
Затем компилируем с g++ main.cpp -I. -o main
g++ main.cpp -I. -o main
(или лязг, g++ main.cpp -I. -o main
же разница) дает мне:
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 включает этот файл types.h, который в строке 194 просто говорит #include <endian.h>
. Мое очевидное заблуждение (и, возможно, чужое) заключалось в том, что угловые скобки предотвратили бы это, но -I сильнее, чем я думал.
Хотя он недостаточно силен, потому что вы даже не можете исправить это, сначала введя /usr/include в командной строке, потому что:
"Если стандартный системный каталог включения или каталог, указанный с
-Isystem
, также указан с-I
, опция-I
игнорируется. Каталог по-прежнему ищется, но как системный каталог на своей обычной позиции в Система включает в себя ".
Действительно, подробный вывод для g++ -v main.cpp -I/usr/include -I. -o main
g++ -v main.cpp -I/usr/include -I. -o main
листья /usr/включают внизу списка:
#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
Цвет меня удивил. Я думаю, чтобы сделать это вопрос:
Какая законная причина для большинства проектов использовать -I
учитывая эту чрезвычайно серьезную проблему? Вы можете переопределить произвольные заголовки в системах на основе случайных конфликтов имен. -Iquote
не все должны вместо этого использовать -Iquote
?