次のマクロがあります。
#define GTR(type) \
type type##_gtr(type a, type b) \
{ \
return a > b ? a : b;\
}
関数を生成することは理解していますが、のGTR(unsigned int)
外側main()
に展開する場合、生成された関数をどのように呼び出すのですか? _gtr(a, b)
動作しません...
unsigned int_gtr(a,b)
作成したマクロ定義では、そのタイプでは機能しないように記述する必要があります。
その理由は、プリプロセッサが単純にtype
パラメータを置き換えて、## の後のテキストに結合するためです。
unisgned int の typedef を作成して、スペースがないようにしてから、それを使用するようなことができます。
typedef unsigned int uint;
GTR(uint)
...
uint_gtr(a,b)
GTR(unsigned)
に拡大します:
unsigned unsigned_gtr(unsigned a, unsigned b)
{
return a > b ? a : b;
}
その場合は、を呼び出す必要がありますunsigned_gtr(a, b)
。
GTR(unsigned int)
ただし、2つの別個のトークンがあり、関数の名前を適切に生成できないため、構文エラーで失敗します。
これ:
type##_gtr
マクロの内部では、type
引数の値とテキストをくっつけています_gtr
。これは、戻り値の型と引数リストの開き括弧の間で発生します。つまり、これが関数の名前を形成します。
したがって、 を使用するGTR(unsigned int)
と、完全な関数プロトタイプが次のようになるため、失敗します。
unsigned int unsigned int_gtr(unsigned int a, unsigned int b)
これは構文的に正しくありません。基本的に、このマクロには、型名にスペースを含めることができないと想定しているという弱点がありますが、これは C には当てはまりません。
ただし、を使用する場合はGTR(unsigned)
、 として呼び出す必要がありますunsigned_gtr()
。