連結演算子 ## は2つの字句を連結して 1 つの字句を作成します。 使用例// コピー名・コピー元・コピー先の組み合わせを記録した配列を初期化する const struct { int cmd; // コマンド識別子 int from; // 複写元の識別子 int to; // 複写先の識別子 } g_copycommand[] = { #define _( from, to ) { ID_COPY_FROM_ ## from ## _TO_ ## to, ID_ ## from, ID_ ## to } _( A, B ), _( A, C ), _( A, D ), _( B, A ), _( B, C ), _( B, D ), _( C, A ), _( C, B ), _( C, D ), _( D, A ), _( D, B ), _( D, C ), #undef _ // #define _( from, to ) };
上記の例で、前処理指令 #define から前処理指令 #undef までのコードは以下のように展開されます。 { ID_COPY_FROM_A_TO_B, ID_A, ID_B }, { ID_COPY_FROM_A_TO_C, ID_A, ID_C }, { ID_COPY_FROM_A_TO_D, ID_A, ID_D }, { ID_COPY_FROM_B_TO_A, ID_B, ID_A }, { ID_COPY_FROM_B_TO_C, ID_B, ID_C }, { ID_COPY_FROM_B_TO_D, ID_B, ID_D }, { ID_COPY_FROM_C_TO_A, ID_C, ID_A }, { ID_COPY_FROM_C_TO_B, ID_C, ID_B }, { ID_COPY_FROM_C_TO_D, ID_C, ID_D }, { ID_COPY_FROM_D_TO_A, ID_D, ID_A }, { ID_COPY_FROM_D_TO_B, ID_D, ID_B }, { ID_COPY_FROM_D_TO_C, ID_D, ID_C },
共通する字句を持つ類似の識別子を上記のように同じ引数から生成すると下記のような単純な間違いは予防することができます。 { ID_COPY_FROM_A_TO_B, ID_A, ID_B }, { ID_COPY_FROM_A_TO_C, ID_A, ID_C }, { ID_COPY_FROM_A_TO_D, ID_A, ID_D }, { ID_COPY_FROM_B_TO_A, ID_B, ID_A }, { ID_COPY_FROM_B_TO_C, ID_B, ID_C }, { ID_COPY_FROM_B_TO_D, ID_B, ID_D }, { ID_COPY_FROM_C_TO_A, ID_C, ID_A }, { ID_COPY_FROM_C_TO_B, ID_C, ID_B }, { ID_COPY_FROM_C_TO_D, ID_C, ID_C }, // おっと! { ID_COPY_FROM_D_TO_A, ID_D, ID_A }, { ID_COPY_FROM_D_TO_B, ID_D, ID_B }, { ID_COPY_FROM_D_TO_C, ID_D, ID_C }, | |