K&R C では、2 つのトークンを連結するために、少なくとも 2 つの方法がありました。次の 2 つの呼び出しは、2 つのトークン x と 1 から 1 つの識別子 x1 を生成します。
#define self(a) a #define glue(a,b) a/**/b ? self(x)1 glue(x,1) |
ISO C では、どちらの方法も使用できません。ISO C では、前述の呼び出しは、両方とも 2 つの別々のトークン x と 1 を生成します。しかし、前述の呼び出しの内 2 番目の方法については、## マクロ置換演算子を使用すれば、ISO C 用に書き換えることができます。
#define glue(a,b) a ## b glue(x, 1) |
# と ## は、__STDC__ が定義されているときだけ、マクロ置換演算子として使用しなければいけません。## は実際の演算子のため、定義と呼び出しの両方で空白をより自由に使うことができます。
コンパイラは、未定義の ## 演算に対して警告の診断を発行するようになりました (C 規格、3.4.3 節)。未定義とは、## を前処理したときの結果に、単一のトークンではなく、複数のトークンが含まれていることを意味します (C 規格、6.10.3.3(3) 節)。未定義の ## 演算の結果は、現在では、## のオペランドを連結することによって作成された文字列をプリプロセスすることによって生成された個別のトークンのうち最初のものと定義されます。
前述の古い形式の連結方法のうち、最初の方法を直接代用できる方法はありません。しかし、この方法では呼び出し時に連結の処理が必要なため、ほかの方法に比べてあまり使用されることはありませんでした。