2.7 Заголовки оболочки ¶
Иногда необходимо скорректировать содержимое файла заголовка, предоставляемого системой, не редактируя его непосредственно. Например, операция GCC fixincludes делает это. Один из способов сделать это — создать новый файл заголовка с тем же именем и поместить его в путь поиска перед исходным заголовком. Это работает нормально, если вы готовы полностью заменить старый заголовок. Но что делать, если вы хотите сослаться на старый заголовок из нового?
Вы не можете просто включить старый заголовок с помощью ‘#include’. Это начнет с самого начала и снова найдет ваш новый заголовок. Если ваш заголовок не защищен от многократного включения (см. Заголовки, включаемые только один раз), он будет рекурсивно включаться бесконечно и приведет к ошибке.
Вы можете включить старый заголовок с абсолютным путем:
#include "/usr/include/old-header.h"
Это работает, но не является чистым решением; если файлы системных заголовков когда-либо переместятся, вам придется отредактировать новые заголовки, чтобы они соответствовали новым местам.
В стандарте C нет способа решить эту проблему, но вы можете использовать расширение GNU ‘#include_next’. Это означает «Включить следующий файл с этим именем». Эта директива работает так же, как ‘#include’, за исключением поиска указанного файла: он начинает поиск в списке каталогов файлов заголовков после каталога, в котором был найден текущий файл.
Предположим, вы укажете -I /usr/local/include, и список каталогов для поиска также включает /usr/include; и предположим, что оба каталога содержат signal.h. Обычный #include <signal.h> находит файл в /usr/local/include. Если этот файл содержит #include_next <signal.h>, он начинает поиск после этого каталога и находит файл в /usr/include.
‘#include_next’ не различает <file> и "file" включения, а также не проверяет, что файл, который вы указали, имеет то же имя, что и текущий файл. Он просто ищет файл с указанным именем, начиная с каталога в пути поиска после того, где был найден текущий файл.
Использование ‘#include_next’ может привести к большой путанице. Мы рекомендуем использовать его только тогда, когда нет других вариантов. В частности, его не следует использовать в заголовках, относящихся к конкретной программе; его следует использовать только для внесения глобальных исправлений по типу fixincludes.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-11.4.0/cpp/Wrapper-Headers.html