我正在研究一些跨平台的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的样式并不感兴趣,而不是将其定义为未定义。如果它具有实际意义,那么我会对洞察力感兴趣。
答案 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
是一种风格或语义重点。