Директива препроцессора #ifdef
выполняет условную компиляцию.Приводит ли это к двоичной несовместимости или нет, зависит от того, что находится между #ifdef
и соответствующим #endif
.Например, следующее явно не будет иметь никакого эффекта вообще:
#ifdef FOO
#endif
Независимо от того, определен ли FOO
, скомпилированный код выглядит точно так же.
Однако следующее будетбезусловно, вызывает несовместимость:
#ifdef HAS_FOO_STRUCT
typedef foo foo_type;
#else
struct foo_type {};
#endif
void bar(foo_type);
Здесь, если HAS_FOO_STRUCT определено, bar(foo_type)
на самом деле bar(foo)
и будет искажено как таковое.С другой стороны, если HAS_FOO_STRUCT
не определено, foo_type
действительно является типом этого имени, таким образом, bar(foo_type)
будет иметь искаженное имя. Это приведет к двоичной несовместимости.
Обратите внимание, чторазличия в определенных макросах могут происходить из нескольких разных мест.Во-первых, разные версии компилятора могут определять разные макросы (или определять макросы для разных значений).Например, есть макросы, определяющие тип системы, на которой вы компилируете, и идентифицирующая версию компилятора.Различия в макросах также могут быть связаны с системными заголовочными файлами, которые могут иметь разные #define
с.Кроме того, система сборки может определять макросы, указывающие, были ли определенные вещи (например, предустановленные библиотеки) обнаружены или не обнаружены в системе.
Обратите внимание, что двоичная несовместимость, которую вы видите, может быть преднамеренной, чтобы предотвратитьстолкновение с более тонкой двоичной несовместимостью, которая не проявляется при компиляции, но вызывает странные ошибки при определенных условиях.