Опять же, как это часто бывает, ответ на вопрос «почему» справедлив: это было сделано именно так, потому что некоторое время назад было решено сделать это таким образом. Когда вы используете неопределенный макрос в #if
, он заменяется на 0. Вы хотите знать, действительно ли он определен - используйте директиву defined()
.
Есть некоторые интересные преимущества этого подхода «по умолчанию в 0». Особенно, когда вы используете макросы, которые могут быть , определяемыми платформой, а не вашими собственными макросами.
Например, некоторые платформы предлагают макросы __BYTE_ORDER
, __LITTLE_ENDIAN
и __BIG_ENDIAN
для определения их порядка байтов. Вы можете написать директиву препроцессора, например
#if __BYTE_ORDER == __LITTLE_ENDIAN
/* whatever */
#else
/* whatever */
#endif
Но если вы попытаетесь скомпилировать этот код на платформе, которая вообще не определяет эти нестандартные макросы (т.е. ничего о них не знает), приведенный выше код будет преобразован препроцессором в
#if 0 == 0
...
и версия кода с прямым порядком байтов будет скомпилирована «по умолчанию». Если вы написали оригинал #if
как
#if __BYTE_ORDER == __BIG_ENDIAN
...
тогда версия кода с прямым порядком байтов будет скомпилирована "по умолчанию".
Я не могу сказать, что #if
было определено так, как это было специально для уловок, подобных приведенным выше, но иногда бывает полезно.