简体   繁体   English

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

[英]Is it possible to compare #ifdef values for conditional use

I'm trying to come up with a generic, easy to use way to only run certain code, depending upon the api I am using at the time. 我试图想出一种通用的,易于使用的方式来运行某些代码,这取决于我当时使用的api。

In a header: 在标题中:

#define __API_USED cocos2d-x

#define COCOS2DX  cocos2d-x
#define OPENGL opengl

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

in source: 来源:

#ifdef USING_COCOS2DX
    ......
#endif

However I don't think this would work. 但是,我不认为这会奏效。

Is there a way to accomplish what I am looking to do? 有没有办法完成我想做的事情?

You can but you need to do it like this: 你可以,但你需要这样做:

#define __API_USED COCOS2DX

#define COCOS2DX  1
#define OPENGL 2

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

As Keith Thompson explained undefined tokens (macros) like cocos2d and x evaluate to 0 so you need to define values for the macros you're using. 正如Keith Thompson解释未定义的令牌(宏),如cocos2dx计算为0因此您需要为您正在使用的宏定义值。

If I understand this correctly, cocos2d-x is one of several possible APIs. 如果我理解正确, cocos2d-x是几种可能的API之一。

The preprocessor can test whether a symbol is defined or not (using #ifdef and the defined operator), and it can evaluate constant integer expressions (using #if ). 预处理器可以测试是否定义了符号(使用#ifdefdefined运算符),它可以计算常量整数表达式(使用#if )。

One approach would be to define a numeric code for each API: 一种方法是为每个API定义数字代码:

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

and then: 然后:

#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

Note that I've changed your macro name __API_USED to API_USED . 请注意,我已将您的宏名称__API_USED更改为API_USED Identifiers starting with two underscores (or with an underscore followed by an uppercase letter) are reserved to the implementation for all purposes; 以两个下划线(或下划线后跟大写字母)开头的标识符保留给实现用于所有目的; you shouldn't define them in your own code. 你不应该在自己的代码中定义它们。

One drawback of this approach is that misspellings won't be flagged; 这种方法的一个缺点是不会标记拼写错误; the preprocessor quietly replaces any undefined identifiers with the constant 0 . 预处理器用常量0静静地替换任何未定义的标识符。

It's probably better to have an identifier for each API, and define it if and only if that API is being used: 为每个API设置一个标识符可能更好,并且当且仅当使用该API时才定义它:

#define USING_COCOS2X
/* #undef USING_COCOS2X */

and then: 然后:

#if USING_API_COCOS2X
    #undef USING_OPENGL
#endif

Testing whether a macro is defined or not tends to be more robust than testing whether it has a specific value. 测试宏是否定义往往比测试宏是否具有特定值更有效。

You then just have to make sure that the USING_API_* macros (if there are several) are defined consistently. 然后,您必须确保USING_API_*宏(如果有多个)一致地定义。

This works for me with clang 8.1.0 (from Xcode 8.3.2). 这对我来说适用于clang 8.1.0(来自Xcode 8.3.2)。 Suppose, in a header file, we want to test CONFIG for the value special . 假设在头文件中,我们要测试CONFIGspecial值。 In any given translation unit, CONFIG might be unset, or might be set to special , or might be set to something else. 在任何给定的翻译单元中, 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

The double indirection ( CAT() calls CAT_HELPER() ) is important. 双重间接( CAT()调用CAT_HELPER() )很重要。

This tactic relies on #if expanding an undefined macro as 0 . 这种策略依赖于#if将未定义的宏扩展为0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM