ゼロ個以上の引数を取る必要がある可変個引数マクロをCで記述する必要があります。
gccでは、これは、コンマの後に「##」を追加することで実現できます。たとえば、引数がゼロの可変個引数マクロで,##____VA_ARGS____
回答されます。
ただし、ビルドシステムのコンパイラー(制御不能)は,##
構文を理解しないため、コンマを飲み込みません。
使用できる回避策はありますか?
ありがとう!
イェンスが綴った簡略版を使用して、可能なアプローチを以下に説明します。
E_
引数を挿入するためにI_
使用され、マクロの間接呼び出しを引き起こすために使用されます。一部のコンパイラV_
では必要と思われる、追加レベルの間接参照を追加する必要があります。
#define V_(...) __VA_ARGS__
#define I_(M,...) V_(M(__VA_ARGS__))
#define E_() _,
MAC
ここで、 0、1、または2つの引数を処理するマクロが必要だとします。
MAC(1, 2);
MAC(1);
MAC();
考えられる実装の1つは、次のようになります。
#define MAC_X(_2,_1,X,...) MAC_##X
#define MAC(...) V_(V_(MAC_X(__VA_ARGS__,2,_))(__VA_ARGS__))
#define MAC_2(...) function_for_2(__VA_ARGS__)
#define MAC_1(...) function_for_1(__VA_ARGS__)
#define MAC_0(...) function_for_0(__VA_ARGS__)
#define MAC_Y(_1,Y,...) MAC_##Y
#define MAC__(...) I_(MAC_Y, E_ __VA_ARGS__ () 0, 1)(__VA_ARGS__)
そしてそれを3つの引数に拡張することは比較的簡単です。唯一の厄介な点は、1つまたは0つの引数を検出することですが、これは変更されません。
-#define MAC_X(_2,_1,X,...) MAC_##X
-#define MAC(...) V_(V_(MAC_X(__VA_ARGS__,2,_))(__VA_ARGS__))
+#define MAC_X(_3,_2,_1,X,...) MAC_##X
+#define MAC(...) V_(V_(MAC_X(__VA_ARGS__,3,2,_))(__VA_ARGS__))
+#define MAC_3(...) function_for_3(__VA_ARGS__)
#define MAC_2(...) function_for_2(__VA_ARGS__)
複数の引数の場合、MAC
マクロはMAC_2
(またはMAC_3
)に展開されます。ただし、引数が1または0の場合、MAC
マクロはに展開されMAC__
ます。
このMAC__
マクロは、Jensのトリックを適用して、1つまたは0つの引数が渡されたかどうかを検出します。これはヘルパーマクロを使用して行い、とのE_
間に引数を挿入すると呼び出されます。引数が0の場合、が呼び出され、引数が挿入されます。挿入された引数は、選択するための2番目の引数になります。引数が1つある場合、は展開されません。toへの最初の引数はになり(ここで、は最初の引数が何であれ)、の2番目の引数はです。これにより、またはのいずれかを呼び出すことができます。E_
()
E_
0
MAC_Y
E_
MAC_Y
E_ ... () 0
...
MAC_Y
1
MAC_Y
MAC_0
MAC_1