C Макросы «препроцессора» оценивают только константы и другие макросы
Краткий ответ: выражение препроцессора обеспечивает только значимую оценку выражения, состоящего из других макросов и констант препроцессора.
Попробуйте, вы не получите сообщение об ошибке:
#if sizeof < 2
int f(int x) { return x; }
#endif
Если вы сгенерируете сборку, вы обнаружите, что sizeof < 2
компилирует функцию, а sizeof >= 2
- нет. Ни один не возвращает ошибку.
Что происходит? Оказывается, что, кроме самих макросов препроцессора, все идентификаторы в выражении препроцессора («макроса») заменяются на 0. Таким образом, вышеприведенный #if
- это то же самое, что и выражение:
#if Easter_Bunny < 2
или
#if 0 < 2
Вот почему на самом деле вы не получаете никакой ошибки, если по ошибке используете оператор sizeof
в выражении препроцессора.
Как оказалось, sizeof
- это оператор, но это также и идентификатор, и идентификаторы, которые сами не являются макросами, превращаются в 0
в выражениях препроцессора. Препроцессор работает, по крайней мере концептуально, перед компилятором. Он может превратить синтаксис не-C в C, поэтому на момент запуска программа C даже не была проанализирована. Пока невозможно сослаться на реальные объекты C: они не существуют.
И, естественно, sizeof
в тексте замены определения просто передается компилятору, а также тексте замены, где используется макрос.