備忘録。
GCC や Clang で利用できる C の拡張機能 __COUNTER__
マクロについて。
概要
__COUNTER__
は __FILE__
や __LINE__
と同様の定義済みマクロ。ただし、参照するたびに展開結果が変わる。
初回は0
に展開され、以降は展開するたびに 1
, 2
, 3
……とインクリメントしていく。例えば以下のコードについて考える。
#include <stdio.h> int main(void) { printf("%d %d %d\n", __COUNTER__, __COUNTER__, __COUNTER__); return 0; }
このプログラムをコンパイルして実行すると以下の出力を得る。
0 1 2
ユースケース
トークン結合演算子と組み合わせて、一意な識別子を生成するのに便利。例えば以下の GEN_FOO
は無名。
#define GEN_FOO(suffix) GEN_FOO_SUB(suffix) #define GEN_FOO_SUB(suffix) foo##suffix GEN_FOO(bar) // => foobar GEN_FOO(__COUNTER__) // => foo0 GEN_FOO(__COUNTER__) // => foo1 GEN_FOO(__COUNTER__) // => foo2
以前に C で RSpec のような記法で書けるテストフレームワークを作った際、before
/after
を実現するために Nested function を利用し、この before
/after
に相当する関数に一意な名前を付けるためにこのテクニックを利用した。