Если вы читаете, например, this C++ #include
reference включенный файл сначала запускается через translation phases от одного до четырех, а phase four запускает препроцессор (рекурсивно).
Это значит, что файл, который вы указали, должен быть заполнен в отношении #if
и #endif
.
Это происходит и в C.
После прочтения спецификации C11 (ISO/IEC 9899: 2011 [2012]), что я думаю это происходит:
Компилятор находится в фазе препроцессора (phase 4) и оценивает #if 1
препроцессор. Условие оценивается как true, поэтому он входит в блок внутри условия. Существует директива #include "test.h"
.
Когда компилятор обрабатывает директиву include, он временно прекращает обработку текущего файла для обработки прилагаемого файла. Эта обработка включенного файла проходит через фазу 1 - 4 компиляции (включительно), прежде чем продолжить с текущим исходным файлом.
Когда обработка самого включаемого файла заголовок приходит к 4-й фазе и начинает обрабатывать #endif
директивы, то он не идет вверх в рекурсивной стеке включения, чтобы найти соответствие #if
, препроцессор просматривает только текущий стек-кадр (текущий файл). Поэтому вы получите первую ошибку около #if
. Стандарт на самом деле ничего не говорит об этом. Все, что он говорит, в основном, состоит в том, что #if
должен иметь соответствие #endif
. То, что компилятор не поднимает стек включения, чтобы найти подходящее значение #if
, похоже, больше детализация реализации.
В любом случае, препроцессор завершает свою обработку файла заголовка с шагом 3 в фазе 4, которая является
В конце этой фазы, все директивы препроцессора удаляются из источника.
Поэтому, когда элемент управления возвращается к предварительной обработке исходного файла, файл, который он фактически включает, не содержит директив предварительной обработки. Все, что включено, это пустой файл, в основном. И это приводит к второй ошибке, что нет #endif
для #if
, потому что на самом деле нет.
Этот ответ ничего не объясняет. Вся препроцессия происходит в одной и той же фазе, поэтому это не помогает понять, что происходит. См. Мой ответ ниже. –