11

標準 C (または GNU 拡張) でマクロ定義に何かを追加する方法はありますか? たとえば、次のように定義されたマクロが与えられた場合、定義したかのように展開されるように
#define List foo bar
追加できますか?basList
#define List foo bar bas

私はこのようなことができることを望んでいました:

#define List    foo bar bas

#define List_   Expand(List)
#undef List
#define List    Expand(List_) quux

しかし、マクロを定義する方法がExpand()わからないので、必要なことを実行します。

動機: 私は、これらの線に沿って、差別された/タグ付けされた組合と遊んでいます:

struct quux_foo { int x; };
struct quux_bar { char *s; };
struct quux_bas { void *p; };

enum quux_type {quux_foo, quux_bar, quux_bas};

struct quux {
    enum quux_type type;
    union {
        struct quux_foo foo;
        struct quux_bar bar;
        struct quux_bas bas;
    } t;
};

これは、X マクロに適した場所だと思います。マクロを定義すると
#define quux_table X(foo) X(bar) X(bas)
、列挙と構造を次のように定義でき、同期が外れることはありません。

#define X(t) quux_ ## t,
enum quux_type {quux_table};
#undef X

#define X(t) struct quux_ ## t t;
struct quux {
    enum quux_type type;
    union {quux_table} t;
};
#undef X

もちろん、quux_*構造が同期しなくなる可能性があるため、合法的にのみ、次のようなことをしたいと思います。

struct quux_foo { int x; };
#define quux_table quux_table X(foo)

struct quux_bar { char *s; };
#define quux_table quux_table X(bar)

struct quux_bas { void *p; };
#define quux_table quux_table X(bas)

(まあ、私が本当にできるようにしたいのは次のような
member_struct(quux, foo) { int x; };
ことですが、マクロはマクロ内から (再) 定義できないことをよく知っています。)

とにかく、それは私の動機付けの例です。これを達成する方法はありますか?

Boost.Preprocessor の例は、そのライブラリで X マクロ手法を機能させる方法を教えていただければ問題ありません。

4

3 に答える 3

7

事実上、いいえ。

マクロは遅延評価されます。の場合#define List_ Expand(List)、その置換リストは、、、、および の 4 つのトークンのシーケンスExpandです。マクロを置換リストに展開する方法はありません。(List)

すべてのマクロ置換は、マクロが呼び出されたときに行われます。

自動コード生成に Boost.Preprocessor ライブラリの使用を検討することをお勧めします。少し手間がかかりますが、これを使用してかなり印象的なことを達成できます。C と完全に互換性がある必要があります。

于 2010-12-30T19:16:22.793 に答える
2

これが役立つかどうかはわかりませんが、可変引数マクロを実行できます。x264 プロジェクトのコンラッド氏は、プリプロセッサの乱用が大好きです。それらが役立つように聞こえる場合は、ここで詳細を確認できます

于 2010-12-28T22:48:05.120 に答える