是否可以比较条件使用的#ifdef值

时间:2014-08-11 23:33:28

标签: c++ conditional c-preprocessor preprocessor-directive

我试图想出一种通用的,易于使用的方式来运行某些代码,具体取决于我当时使用的api。

在标题中:

#define __API_USED cocos2d-x

#define COCOS2DX  cocos2d-x
#define OPENGL opengl

#ifdef __API_USED == COCOS2DX
    #define USING_COCOS2DX
    #undef USING_OPENGL
#endif

来源:

#ifdef USING_COCOS2DX
    ......
#endif

但是,我认为这不会起作用。

有没有办法完成我想做的事情?

3 个答案:

答案 0 :(得分:10)

你可以但你需要这样做:

#define __API_USED COCOS2DX

#define COCOS2DX  1
#define OPENGL 2

#if __API_USED == COCOS2DX
    #define USING_COCOS2DX
    #undef USING_OPENGL
#endif

正如Keith Thompson解释未定义的令牌(宏),如cocos2dx评估为0所以你需要为你正在使用的宏定义值。

答案 1 :(得分:4)

如果我理解正确,cocos2d-x是几种可能的API之一。

预处理器可以测试是否定义了符号(使用#ifdefdefined运算符),它可以计算常量整数表达式(使用#if)。

一种方法是为每个API定义数字代码:

#define COCOS2X         1
#define ANOTHER_API     2
#define YET_ANOTHER_API 3
/* ... */

然后:

#define API_USED COCOS2DX
#if API_USED == COCOS2DX
    #define USING_COCOS2DX
    #undef USING_OPENGL
#elif API_USED == ANOTHER_API
    /* ... */
#elif API_USED == YET_ANOTHER_API
    /* ... */
#endif

请注意,我已将您的宏名称__API_USED更改为API_USED。以两个下划线(或下划线后跟大写字母)开头的标识符保留给实现用于所有目的;你不应该在自己的代码中定义它们。

这种方法的一个缺点是拼写错误不会被标记;预处理器使用常量0静静地替换任何未定义的标识符。

最好为每个API设置一个标识符,并且当且仅当使用该API时才定义它:

#define USING_COCOS2X
/* #undef USING_COCOS2X */

然后:

#if USING_API_COCOS2X
    #undef USING_OPENGL
#endif

测试是否定义宏往往比测试是否具有特定值更有效。

然后,您必须确保USING_API_*宏(如果有多个)一致定义。

答案 2 :(得分:0)

这适用于clang 8.1.0(来自Xcode 8.3.2)。假设在头文件中,我们要测试值CONFIG的{​​{1}}。在任何给定的翻译单元中,special可能未设置,或者可能设置为CONFIG,或者可能设置为其他内容。

special

双重间接(#define CAT_HELPER(lhs, rhs) lhs##rhs #define CAT(lhs, rhs) CAT_HELPER(lhs, rhs) #define TEST_PREFIX_special 1 #if CAT(TEST_PREFIX_, CONFIG) #pragma message("detected CONFIG == 'special'") #else #pragma message("CONFIG != 'special'") #endif 调用CAT())很重要。

此策略依赖于CAT_HELPER()将未定义的宏扩展为#if