Должны ли совпадать пути #include в файле C и директива -I, переданная GCC?

#c #include #freertos

#c #включить #freertos

Вопрос:

Я смотрю на демонстрационный проект FreeRTOS для порта AVR. Makefile имеет пути к каталогам, в которых находятся исходные файлы RTOS, с помощью директивы «-I». Однако в модуле main.c проекта #include не предоставляет никакого подобного пути:

 #include "FreeRTOS.h"
  

Итак, я не могу понять, требуется ли директива «-I» только для компоновщика для поиска объектных файлов? Означает ли это также, что после компиляции файлов в объектный код для GCC они, по сути, лежат в одной папке, если он знает, где искать?

У меня эта путаница, потому что я видел #include подобные инструкции ранее:

 #include <avr/io.h>
  

Если GCC уже знает местоположение ввода-вывода.h зачем включать перед ним часть «avr»?

Комментарии:

1. У вас это немного наоборот. -I сообщает компилятору выполнить поиск по этому пути, чтобы найти файлы заголовков. Именно по этой причине #include "FreeRTOS.h" путь не нужен. Если бы не было, -I тогда вам нужно было бы указать полный путь в #include (что является плохой практикой).

Ответ №1:

Когда мы говорим

 #include <foo/bar.h>
  

компилятор обычно ищет файл с именем bar.h в каталоге с именем foo в одном из мест, где он настроен для поиска заголовков. Например, стандартный путь поиска в заголовке обычно содержит `/usr/include’, поэтому файл ‘bar.h’ будет найден, если он существует, в ‘/usr/include/foo’.

Если вы используете -I переключатель, подобный этому:

 -I /usr/include/foo
  

вы могли бы в качестве альтернативы написать

 #include <bar.h>
  

потому что вы включили каталог foo в путь поиска заголовка компилятора.

Однако, если foo это какая-то библиотека или модуль, вероятно, более выразительно использовать вариант #include , который включает подкаталог foo , вместо того, чтобы манипулировать путем поиска в заголовке, чтобы вам не приходилось этого делать.

Для записи -I переключатель не оказывает прямого влияния на поведение компоновки.

Кстати, вариант

 #include "foo/bar.h"
  

обычно указывается файл в каталоге foo в том же каталоге, что и исходный файл. Однако современные компиляторы, похоже, также применяют пути заголовка поиска к этим директивам. Я не уверен, является ли это поведением, основанным на стандартах, или просто авторы компилятора пытаются угадать наши намерения.