web-dev-qa-db-ja.com

条件付きで使用するために#ifdef値を比較することは可能ですか?

私は、その時点で使用している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

しかし、私はこれがうまくいくとは思いません。

私がやろうとしていることを達成する方法はありますか?

11
Jason

できますが、次のようにする必要があります。

#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に評価されるため、使用しているマクロの値を定義する必要があります。

14
Ross Ridge

これを正しく理解していれば、cocos2d-xはいくつかの可能なAPIの1つです。

プリプロセッサは、シンボルが定義されているかどうかをテストでき(#ifdefおよびdefined演算子を使用)、定数整数式を評価できます(#ifを使用)。

1つのアプローチは、各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に変更したことに注意してください。 2つのアンダースコアで始まる(またはアンダースコアの後に大文字が続く)識別子は、すべての目的で実装用に予約されています。独自のコードでそれらを定義するべきではありません。

このアプローチの欠点の1つは、スペルミスのフラグが立てられないことです。プリプロセッサは、未定義の識別子を定数0で静かに置き換えます。

APIごとに識別子を設定し、そのAPIが使用されている場合にのみ定義することをお勧めします。

#define USING_COCOS2X
/* #undef USING_COCOS2X */

その後:

#if USING_API_COCOS2X
    #undef USING_OPENGL
#endif

マクロが定義されているかどうかのテストは、特定の値があるかどうかのテストよりも堅牢になる傾向があります。

次に、USING_API_*マクロ(複数ある場合)が一貫して定義されていることを確認する必要があります。

5
Keith Thompson

これは、clang 8.1.0(Xcode 8.3.2から)で機能します。ヘッダーファイルで、値CONFIGについて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_として展開する_0_に依存しています。

0
Nat Goodspeed