8.6 トークン連結
8.6.1 トークン連結演算子
#define を用いたマクロ専用のプリプロセッサ演算子で、文字列化演算子の他にもうひとつ重要な演算子が存在します。それは、2つのシャープ記号からなる ## 演算子で、トークン連結演算子とも呼ばれます。この演算子は、通常のマクロと関数型マクロで有効です。
トークン1 ## トークン2
トークン連結演算子は左辺のトークンと右辺のトークンを接合します。トークンの接合は、単純に C 言語のソースレベルのテキストをプリプロセッサによって連結させるだけであり、プログラムが動的に接合させるものではないということに注意してください。例えば、マクロで WIN ## 32 を指定すれば WIN32 というトークンに連結されますし、WIN ## 16 とすれば WIN16 になります。マクロ関数の引数とトークン連結演算子を使えば、マクロを用いてトークンの指定を隠蔽するということができるようになります。
#define INT16 short #define INT32 int #define INT(n) INT ## n
上記の INT() マクロ関数は INT というトークンと n パラメータを接続します。例えば INT(16) と指定した場合は INT16 に展開され、さらに INT16 のマクロが処理され、最終的には short に展開されます。
#include <stdio.h> #define TOKEN0 "Kitty" #define TOKEN1 "Kitten" #define TOKEN(n) TOKEN ## n int main() { printf("%s\n" , TOKEN(0)); printf("%s\n" , TOKEN(1)); return 0; }

コード1の TOKEN() マクロ関数は、引数に連結するトークンを受け取ります。プログラムの仕様から、引数に指定できる値は 0 または 1 のいずれかです。例えば TOKEN(0) を指定した場合は、これが TOKEN ## 0 と解釈され、これらのトークンが結合して、最終的には TOKEN0 に展開されます。TOKEN0 という名前は #define で定義されている名前なので、問題ありません。
このように、トークン連結演算子を用いて結合された新しいトークンは、必ず有効なトークンでなければなりません。無効なトークンであれば、当然コンパイル時にエラーが発生します。トークンの連結はプリプロセッサがコンパイル前に処理するソースレベルの展開に過ぎないことを忘れないで下さい。