2011年11月10日木曜日

g++とvc++の可変引数マクロの挙動の違い

g++は4.5,vc++は2010.

例えば可変引数マクロのとる引数の個数を数えたいと思ったとき,g++ならこう書けばOK.

#define NUM_ARGS(...) NUM_ARGS_I(__VA_ARGS__,8,7,6,5,4,3,2,1)

#define NUM_ARGS_I(_1,_2,_3,_4,_5,_6,_7,_8,n,...) n

int main(){
  // g++では4に展開される
  std::cout << NUM_ARGS(one,two,three,four) << std::endl; 
}


ところがこれ,vc++では意図通り動作せず,1が出力される.
どうもvc++では,NUM_ARGS_Iの引数が,

_1 = one,two,three,four
_2 = 8
_3 = 7
...
_8 = 2
n = 1

と展開されるようだ.これってC99の規格に沿ってるんだろうか?

vc++でもきちんと動かすには,一度タプル化するのがお手軽っぽい.
実際にboost.preprocessorでもこの手が使われている.

#define NUM_ARGS(...) NUM_ARGS_I( (__VA_ARGS__,8,7,6,5,4,3,2,1) )

#define NUM_ARGS_I(tuple) NUM_ARGS_II tuple

#define NUM_ARGS_I(_1,_2,_3,_4,_5,_6,_7._8,n,...) n

0 件のコメント:

コメントを投稿