Если вы читаете, например. данный #include
справочник по C++ включаемый файл сначала проходит через этапы перевода с первого по четвертый и четвертая фаза запускает препроцессор (рекурсивно).
Это означает, что файл, который вы включаете, должен быть полным в отношении #if
и #endif
.
Это происходит и в C.
Прочитав спецификацию C11 (ISO/IEC 9899:2011 [2012]), думаю, происходит следующее:
Компилятор находится на этапе препроцессора (этап 4) и оценивает #if 1
директива препроцессора. Условие оценивается как истинное, поэтому оно входит в блок внутри условия. Видит директиву #include "test.h"
.
Когда компилятор обрабатывает директиву include, он временно останавливает обработку текущего файла, чтобы обработать включенный файл. Эта обработка включенного файла проходит этапы компиляции с 1 по 4 (включительно), прежде чем продолжить работу с текущим исходным файлом.
Когда обработка самого включенного заголовочного файла доходит до фазы 4 и начинает обрабатывать директиву #endif
, то он не поднимается вверх в стеке рекурсивного включения, чтобы найти соответствующий #if
, препроцессор только ищет в текущем кадре стека (текущем файле). Поэтому вы получаете первую ошибку об отсутствии #if
. На самом деле стандарт ничего не говорит об этом. В основном это говорит о том, что #if
должно соответствовать #endif
. То, что компилятор не поднимается по стеку включения, чтобы найти соответствие #if
, похоже, больше относится к деталям реализации.
В любом случае, препроцессор заканчивает обработку заголовочного файла на шаге 3 в фазе 4, т.е.
В конце этой фазы все директивы препроцессора удаляются из исходного кода.
Поэтому, когда элемент управления возвращается к предварительной обработке исходного файла, файл, который он фактически включает, не содержит никаких директив предварительной обработки. Все, что включено, это пустой файл, в основном. И это приводит ко второй ошибке, что для #if
нет #endif
, потому что его действительно нет.
person
Some programmer dude
schedule
14.10.2016