式の評価結果が指定した型かどうかを判別する
今回のマクロは、式の評価結果が整数型かどうかを判別すると似ているのですが、整数型にかぎらず、指定した型と完全に一致するかどうかを判別するためのものです。指定した型と一致しない場合はコンパイルエラーになります。なお、GCC拡張を使用していますので、GCC限定になり、移植性はありません。
#define assert_type(x, type) assert_type_((x), type, __LINE__)
#define assert_type_(x, type, line) assert_type2_(x, type, line)
#define assert_type2_(x, type, line) \
({void aSseRt_tYpE_##line(type);void aSseRt_tYpE_##line(__typeof__(x));})
#define assert_type_(x, type, line) assert_type2_(x, type, line)
#define assert_type2_(x, type, line) \
({void aSseRt_tYpE_##line(type);void aSseRt_tYpE_##line(__typeof__(x));})
GCCでは、複合文を丸括弧で囲むことで式にすることができます。逆にいえば、式の中に複合文を入れることができるわけで、複合文を入れられるということは宣言を含めることができます。
このマクロの原理は、式中の複合文で、同じ関数の宣言を2度繰り返しています。1度目は、仮引数に指定した型をあてています。2度目は、仮引数に指定した式をオペランドとする__typeof__演算子をあてています。__typeof__演算子もGCC拡張で、オペランドの型に置き換わります。マクロの引数で指定した式の評価結果の型と、やはり引数で指定した型が一致すれば、二つの関数宣言は等価になるはずですのでコンパイルできます。そうでなければ、Cでは多重定義ができませんのでコンパイルエラーになります。
この記事のトラックバックURL:
http://www.kijineko.co.jp/trackback/755

