3

私のコードが次のスニペットのようになっていると仮定します。

#ifdef COND1
    extern int func1(void);
#endif
...
#ifdef CONDN
    extern int funcn(void);
#endif

my_struct funcs[] = {
#ifdef COND1
    {"func1 description", func1},
#endif
...
#ifdef CONDN
    {"funcn description", funcn},
#endif
    {NULL, NULL},
};

両方の部分で関数名と条件の繰り返しを最小限に抑えるために、これをX マクロに置き換えることは可能ですか?

条件がなければ#ifdef CONDX、これは非常に簡単に見えます。#ifdefただし、.a での使用が許可されていないため、X マクロに含める方法がわかりません#define

4

5 に答える 5

0

ここでX マクロが解決策になるかどうかはわかりません。ただし、プリプロセッサ マジックを少し使用して、タイピングを減らすことができます。問題は、例の条件付きコンパイル ( #ifdefs) のままです。これらの条件がどのように見えるかを知らなければ、タイピングの量をさらに減らすことは困難です。

次のことを考慮してください。

#define D(n) extern int func ## n(void);
#define A(n) {"func" #n " description", func ## n},

#ifdef COND1
  D(1)
#endif
#ifdef COND2
  D(2)
#endif

my_struct funcs[] = {
#ifdef COND1
  A(1)
#endif
#ifdef COND2
  A(2)
#endif
};

これは、あなたが目指している方向への一歩だと思います。これが何をするかを見るために、あなたは試すことができます

gcc -E -DCOND1 <file-with-contents-above>.c

(一部の Unix を使用している場合) または

cl -E -DCOND1 <file-with-contents-above>.c

(Windows で Visual Studio を使用している場合)。

于 2015-06-04T12:14:54.673 に答える
0

#ifdef内部では使用#defineできないため、#defineベースの X マクロは使用できませんが、ベースの X マクロは引き続き使用でき#includeます。

たとえば、次のファイルを使用しますt.def

#ifdef COND1
F(func1, "func1 description")
#endif
#ifdef COND2
F(func2, "func2 description")
#endif

そして、あなたのプライマリファイルで:

#define COND2

#define F(name, desc) extern int name(void);
#include "t.def"
#undef F

mystruct funcs[] = {
    #define F(name, desc) {desc, name},
    #include "t.def"
    #undef F
    {NULL, NULL},
};

これは次のように処理されます。

extern int func2(void);

mystruct funcs[] = {
    {"func2 description", func2},
    {NULL, NULL},
};
于 2015-06-04T12:27:54.403 に答える
0

COND1 を定義したいが、CONDN は定義したくないとします。次のことができると思います。

#define COND1(...) __VA_ARGS__
#define CONDN(...)

#define MY_XLIST \
    X(COND1, func1, "func1 description") \
    X(CONDN, funcn, "funcn description")

#define X(a, b, c) a(extern int b (void);)
MY_XLIST
#undef X

#define X(a, b, c) a({c, b},)
my_struct funcs[] = {
    MY_XLIST
    {NULL, NULL},
};
#undef X

問題は、すべてのマクロを定義する必要がありますが、展開が異なることです。

于 2015-06-04T12:25:49.483 に答える