Люди recommend #ifdef
for conditional compilation by a wide margin. A search for #ifdef
обосновывает, что его использование широко распространено.Почему люди используют #ifdef для тестирования флагов объектов?
Еще #ifdef NAME
(или, что эквивалентно #if defined(NAME)
и связанной с ними #ifndef NAME
(и #if !defined(NAME)
) имеют серьезный недостаток:
header.h
#ifndef IS_SPECIAL
#error You're not special enough
#endif
source.cpp
#include "header.h"
НКУ - DIS_SPECIAL source.cpp
пройдет, очевидно, как будет
source1.cpp
#define IS_SPECIAL 1
#include "header.h"
Но, так будет
source0.cpp
#define IS_SPECIAL 0
#include "header.h"
, который совсем не то делать. И некоторые компиляторы C++ передали файл, обработанный в режиме C (из-за расширения или опции командной строки) эффективно делают #define __cplusplus 0
. Я видел вещи ломаются, когда
#ifdef __cplusplus
extern "C" {
#endif
/* ... */
#ifdef __cplusplus
}
#endif
был обработан в C режима, где extern "C"
недействителен синтаксис, поскольку __cplusplus
был фактически автоматически определен в 0
.
С другой стороны, это ведет себя правильно для всех компиляторов:
#if __cplusplus
extern "C" {
#endif
/* ... */
#if __cplusplus
}
#endif
Почему люди до сих пор используют #ifdef
в этом сценарии? Неужели они просто не знают, что #if
отлично работает с неопределенными именами? Или есть ли недостаток #if
против #ifdef
для условной компиляции?
Очевидно, что #ifdef
имеет действительные применения, такие как обеспечение значения по умолчанию для настраиваемых параметров:
#ifndef MAX_FILES
#define MAX_FILES 64
#endif
Я только обсуждающих случай тестирования флага.
Почему это «совсем не то, что нужно делать»? Условие задает вопрос о том, что-то определено, и оно определено в обоих случаях. Можно было бы ожидать тех же результатов, нет? –
@JoshuaTaylor: Это означает, что компилятор правильно выполнил тест. Это не означает, что пользователь выбрал правильный тест. См. Обсуждение '__cplusplus == 0', потому что это неправильный тест. Или вы считаете, что изменение параметра от «1» до «0» не должно отключать его? –
To downvoter: Мне любопытно, что вы думаете, что этот вопрос плохо исследован? Это потому, что я не цитировал разделы Стандарта, которые имеют дело с '# if' и неопределенными макросами? Потому что вы не думаете, что ответ имеет практическую ценность? Потому что вопрос плохо написан и не может быть понят обычными программистами на C и C++? Я рад попытаться улучшить его, если вы дадите обратную связь. –