2016-01-11 6 views
5

ここではマクロが引数の数を計算できます。等のコード:このCマクロの意味は何ですか?

#define Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0 

Y_TUPLE_SIZE_PREFIX_ ## __VA_ARGS__ ## _Y_TUPLE_SIZE_POSTFIX 

を理解するためにどのように

#define Y_TUPLE_SIZE_II(__args) Y_TUPLE_SIZE_I __args 
#define Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIX ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0 

#define Y_TUPLE_SIZE_I(__p0,__p1,__p2,__p3,__p4,__p5,__p6,__p7,__p8,__p9,__p10,__p11,__p12,__p13,__p14,__p15,__p16,__p17,__p18,__p19,__p20,__p21,__p22,__p23,__p24,__p25,__p26,__p27,__p28,__p29,__p30,__p31,__n,...) __n 

#define MPL_ARGS_SIZE(...) Y_TUPLE_SIZE_II((Y_TUPLE_SIZE_PREFIX_ ## __VA_ARGS__ ## _Y_TUPLE_SIZE_POSTFIX,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) 

// the running result --------------------------------------- 

MPL_ARGS_SIZE(a,b,c,d,e,f,g)==7 

MPL_ARGS_SIZE(a,b,c,d)==4 

ところで、私は##(ポンド、ポンド)用法及びY_TUPLE_SIZE_I

+1

これは非常に狂ったマクロセットです。 – immibis

+0

あなたは、渡すための空の引数の束を形成しています(そして0)。それらを連結した後、引数リストを取得します。しかし、これは議論のカウンターマクロにとって必要以上に少しのようです。私はあなたがおそらく1の代わりに0を与える 'MPL_ARGS_SIZE()'のケースを扱っていると思います。 – chris

+0

@chrisいいえ、空の引数は引数が与えられていない場合にのみ出現します。特別なケースです。通常の場合、空の引数はありません。 –

答えて

2

PREFIXとPOSTFIXマクロは引数が与えられなかったときには0を与える作ることを意図しているの#defineのメカニズム、すなわちMPL_ARGS_SIZE()について知っています。連結は、単に与えられた引数の数が同じに展開ように、この場合には、Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIXは、一般的なケースでは0

に結果を強制Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIXを生成するために連結され、__VA_ARGS__は、空ではありません。これに続いて32、... 0が続きます。

どちらの場合も、引数はかっこで囲まれています。 Y_TUPLE_SIZE_IIはこれらの余分なカッコを取り除き、引数をY_TUPLE_SIZE_Iに渡します。 Y_TUPLE_SIZE_Iは33番目の引数に展開され、残りは破棄されます。

32個の引数を渡すと、32個の引数がスキップされ、32個後の数値が必要に応じて結果になります。 31個の引数を指定すると、それらの31個をスキップし、最初の番号、つまり32個をスキップし、結果は次の番号31になります。

あなたはそれを単一の引数を与えた場合、それはその引数と、それに続く31をスキップします、そしてあなたはそれを引数を与えない場合は、Y_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIXの特殊なケースがに来る結果は1

になりますプレイは空の32個の引数の後に0が続きます.32個の空の引数はスキップされ、結果は0になります。

引数がないという特別な理由は、それがなければ、 1つの議論の場合。次はそれをよりよく理解するのに役立つかもしれない:

#define Y_TUPLE_SIZE_II(__args) Y_TUPLE_SIZE_I __args 
#define Y_TUPLE_SIZE_I(__p0,__p1,__p2,__p3,__p4,__p5,__p6,__p7,__p8,__p9,__p10,__p11,__p12,__p13,__p14,__p15,__p16,__p17,__p18,__p19,__p20,__p21,__p22,__p23,__p24,__p25,__p26,__p27,__p28,__p29,__p30,__p31,__n,...) __n 

#define MPL_ARGS_SIZE(...) Y_TUPLE_SIZE_II((__VA_ARGS__,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) 

これは、マクロの元のセットであるが、特殊なケースのすべてが削除さゼロの引数を扱うと。 0以外の場合は0を返します。

ゼロ引数を処理するために、引数マクロはプレフィックスマクロとポストフィックスマクロの間にサンドイッチします。結果がY_TUPLE_SIZE_PREFIX__Y_TUPLE_SIZE_POSTFIXに展開されると、引数リストは空になり、特別な場合が発生します。

+0

まあ、メソッド 'Y_TUPLE_SIZE_II((__ VA_ARGS __、32 ... 0))'はわかりやすいものでした。しかし引数がa、b、cの場合、 '#define MPL_ARGS_SIZE(...)Y_TUPLE_SIZE_II((Y_TUPLE_SIZE_PREFIX_ ## __VA_ARGS__ ## _Y_TUPLE_SIZE_POSTFIX、...)'に戻ります。例えば、 MPL_ARGS_SIZE(a、b、c) '?Y_TUPLE_SIZE_II((Y_TUPLE_SIZE_PREFIX_a、b、c_Y_TUPLE_SIZE_POSTFIX、... 0))'と思われます。もちろん、それは間違ったステートメントです、それを理解する方法? –

+0

最初の引数と最後の引数は接頭辞と接尾辞の文字列によって変更されますが、引数の役割を果たす唯一の目的は問題ではないので、最終結果ではすべて破棄されます –

+0

oooops 'Y_TUPLE_SIZE_II((Y_TUPLE_SIZE_PREFIX_a、b、c_Y_TUPLE_SIZE_POSTFIX、... 0)'は 'Y_TUPLE_SIZE_I(Y_TUPLE_SIZE_PREFIX_a、b、c_Y_TUPLE_SIZE_POSTFIX、... 0)'として展開され、PREFIX_a、b、c_POSTFIXどちらも 'Y_TUPLE_SIZE_I'マクロのパラメータとして使用されます。 –

関連する問題