私のプロジェクト用に x マクロ ベースのレジスタ ファイル レイアウト記述システムを作成しています。ほとんどの場合、マクロはテンプレート クラスの階層に展開されます。ただし、次のように、すべてのレジスタの列挙も必要です。
#define RINT(num,name,flags,width) name,
...
enum Regs
{
#include REGDEF
};
これはうまくいきます。ただし、可変個引数マクロを使用してエイリアシング レジスタも指定します。__VA_ARGS__ の要素間のコンマを削除する簡単な方法がないため (私が知っていることではないので、間違っている場合は訂正してください)、次のように記述します。
#define RALIAS_10(r0,r1,r2,r3,r4,r5,r6,r7,r8,r9) r0 r1 r2 r3 r4 r5 r6 r7 r8 r9
#define RALIAS_9(r0,r1,r2,r3,r4,r5,r6,r7,r8) r0 r1 r2 r3 r4 r5 r6 r7 r8
...
#define RALIAS_1(r0) r0
#define RALIAS_N(d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,aliasn,...) aliasn
#define RALIAS(...) RALIAS_N(__VA_ARGS__, RALIAS_10(__VA_ARGS__), RALIAS_9(__VA_ARGS__), ..., RALIAS_1(__VA_ARGS__))
さて、書いてみると
RALIAS(RINT(4, RSP, 0, 64), RINT(4, ESP, 0, 32), RINT(4, SP, 0, 16), RINT(4, SPL, 0, 8))
RINT マクロのコンマが消えます。
enum Reg
{
...
RSP ESP SP SPL
...
};
次に、RALIAS_4 マクロを直接使用する場合
RALIAS_4(RINT(4, RSP, 0, 64), RINT(4, ESP, 0, 32), RINT(4, SP, 0, 16), RINT(4, SPL, 0, 8))
私が期待するものを手に入れます:
enum Reg
{
...
RSP, ESP, SP, SPL,
...
};
GCC がいくつかの非標準のカンマ除去ロジックを可変個引数マクロに適用することは知っていますが、-std=c++11 を明示的に指定した場合はそうすべきではありません。さらに、Clang でまったく同じ結果が得られました。それでも、標準 (ドラフト) や GCC のドキュメントでこの動作を説明するものを見つけることができませんでした。
私は何が欠けていますか?
Arch Linux (x86-64) で GCC 6.1.1 と Clang 3.8.1 を試しました。両方のコンパイラがリポジトリからインストールされました。