是否有一个实际的理由" #if定义(X)&& (X!= 0)"?

时间:2015-01-06 23:26:07

标签: preprocessor c-preprocessor preprocessor-directive

我正在研究一些跨平台的prerpocessor宏。对于Microsoft,我读了the following should be used

#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
#   SOME_SETTING_FOR_MY_PROJECT
#endif

以上几点是在使用该值之前对WINAPI_FAMILY进行的显式测试。 (我很确定未定义的宏的计算结果为0)。

对于Apple,部分samples on their website use

#if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
#   SOME_SETTING_FOR_MY_PROJECT
#endif

以上几点是Apple的样本没有使用#if defined(TARGET_OS_IPHONE) && (TARGET_OS_IPHONE != 0)

是否比另一个更便携?

是否有一个实际的理由使用一个与另一个?或者这是一个风格问题?

注意:我对定义一些为0的样式并不感兴趣,而不是将其定义为未定义。如果它具有实际意义,那么我会对洞察力感兴趣。

1 个答案:

答案 0 :(得分:1)

即使未定义的宏默认为零(参见gcc),但未定义的宏与有意设置为零的宏之间存在差异。

当然,这对于像WINAPI_FAMILY这样的宏没有多大意义,因为它的唯一有效值是1和2.但是某些宏可能在值0后面具有合法含义,意义可能与未定义的宏不同。

例如,考虑一个可以分配给特定级别(LOG_LEVEL宏)的日志级别(LOG_xxx)的宏。如果它没有被用户定义,它应该默认为LOG_ERROR(2而不是0)。

#define LOG_NONE     0
#define LOG_WARNING  1
#define LOG_ERROR    2
#define LOG_FATAL    3

现在,如果您只检查LOG_LEVEL的值并且尚未由用户或编译器定义,则默认为LOG_NONE而不是LOG_ERROR。因此,在这种情况下,您还需要进行defined检查。

但除此之外,我认为在大多数情况下更多的是代码风格。我找不到任何没有默认宏值为零的C编译器,所以在你的情况下使用defined的主要原因是强调这不仅仅是一个值检查,而且还认为宏可能不是设置完毕。

tldr; 未定义并设置为零并不是一回事;但在大多数情况下,使用defined是一种风格或语义重点。