Is it possible to compare #ifdef values ​​for conditional use

I am trying to create a generic, easy-to-use way to run certain code, depending on the api I use at the time.

In the title:

#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 do not think this will work.

Is there a way to accomplish what I'm looking for?

+5
source share
3 answers

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 Kate Thompson explained undefined tokens (macros), such as cocos2d and x , evaluate to 0 , so you need to determine the values ​​for the macros you use.

+7
source

If I understand this correctly, cocos2d-x is one of several possible APIs.

The preprocessor can check whether a character is defined or not (using #ifdef and the defined operator), and it can evaluate constant integer expressions (using #if ).

One approach would be to define a numerical code for each 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 changed the macro name __API_USED to API_USED . Identifiers starting with two underscores (or with an underscore followed by an uppercase letter) are reserved for implementation for all purposes; you should not define them in your own code.

One of the drawbacks of this approach is that spelling errors will not be flagged; the preprocessor quietly replaces undefined identifiers with constant 0 .

It is probably best to have an identifier for each API and define it if and only if this API is used:

 #define USING_COCOS2X /* #undef USING_COCOS2X */ 

and then:

 #if USING_API_COCOS2X #undef USING_OPENGL #endif 

Testing whether a macro is defined or not is more reliable than checking if it has a specific meaning.

You just need to make sure that the USING_API_* macros (if there are several) are defined sequentially.

+3
source

This works for me with clang 8.1.0 (from Xcode 8.3.2). Suppose in the header file we want to test CONFIG for the value special . In any given translation unit, CONFIG can be disabled or can be set to special or can be set to something else.

 #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 

Double indirect ( CAT() calls to CAT_HELPER() ) are CAT_HELPER() .

This tactic is based on the #if macro extension undefined as 0 .

0
source

Source: https://habr.com/ru/post/1200068/


All Articles