web-dev-qa-db-ja.com

Cプリプロセッサの#define内で#ifを使用する方法は?

パラメータのブール値に基づいてコードを吐き出すマクロを書きたいのですが。したがって、DEF_CONST(true)constに展開され、DEF_CONST(false)は何にも展開されないはずです。

#defines内で別のプリプロセッサを使用できないため、明らかに以下は機能しません。

#define DEF_CONST(b_const) \
#if (b_const) \
  const \
#endif
48
Wxy

次のように マクロトークン連結 を使用して条件をシミュレートできます。

#define DEF_CONST(b_const) DEF_CONST_##b_const
#define DEF_CONST_true const
#define DEF_CONST_false

そして、

/* OK */
DEF_CONST(true)  int x;  /* expands to const int x */
DEF_CONST(false) int y;  /* expands to int y */

/* NOT OK */
bool bSomeBool = true;       // technically not C :)
DEF_CONST(bSomeBool) int z;  /* error: preprocessor does not know the value
                                of bSomeBool */

また、マクロパラメータをDEF_CONST自体に渡すことを許可します(GManや他の人が正しく指摘しているように):

#define DEF_CONST2(b_const) DEF_CONST_##b_const
#define DEF_CONST(b_const) DEF_CONST2(b_const)
#define DEF_CONST_true const
#define DEF_CONST_false

#define b true
#define c false

/* OK */
DEF_CONST(b) int x;     /* expands to const int x */
DEF_CONST(c) int y;     /* expands to int y */
DEF_CONST(true) int z;  /* expands to const int z */

また、はるかに単純である可能性もあります(ただし、柔軟性が低くなる可能性があります)。

#if b_const
# define DEF_CONST const
#else /*b_const*/
# define DEF_CONST
#endif /*b_const*/
50
vladr

パラメータ化されたマクロとしてそれを行うのは少し奇妙です。

なぜこのようなことをしないのですか?

#ifdef USE_CONST
    #define MYCONST const
#else
    #define MYCONST
#endif

次に、次のようなコードを記述できます。

MYCONST int x = 1;
MYCONST char* foo = "bar";

USE_CONSTを定義してコンパイルした場合(通常、メイクファイルまたはコンパイラオプションで何か-DUSE_CONSTなど)、constsを使用します。それ以外の場合は使用しません。

編集:実際には、ウラッドが答えの最後にそのオプションをカバーしているので、彼に+1します:)

7
GrahamS