GCCC 4.7+の中で、C 11の_をどうやって代替しますか?ジェネリック

6114 ワード

C 11規格において、非常に重要な特性更新は、Generac Selectionという特性を増加させることである.この特性は、C 11が軽量級の汎型プログラミングをサポートすることができ、異なるタイプの関数のセットを一つのインターフェースとして抽象化することができる.
に対してGenericの使用は私のこのブログを参照してください.http://www.cnblogs.com/zenny-chen/archive/2012/09/20/2695381.html
GCCはまだC 11規格のGenerc Selectionをサポートしていませんが、GCCは4.0バージョンからいくつかのビルドされたコンパイル時関数(これらの関数はsizofに類似しています)をサポートしています.ここでは、グループを通じて_u u u u u u u u u u u u u u u u u uを使用します.builting.チョイスexpr及び__builting.types_comptiblepはC 11のGenerc Selection機能を実現する.
まず私たちはちょっと見てみますbuilting.チョイスexprの原型:
type __builtin_choose_expr (const_exp, exp1, exp2)
ここで注意したいのは、この関数の最初のパラメータは定数式でなければなりません.以前にも述べたように、コンパイル時の挙動ではなく、実行時の挙動です.sizefやtypeofと同じです.この関数は述語関数で、もしconst_exprの結果は0ではないので、exp 1を生成し、戻りタイプタイプtypeもexp 1式のタイプと一致します.そうでなければ、exp 2が生成され、戻りタイプtypeもexp 2のタイプと一致します.コンパイル時の挙動なので、exp 1とexp 2の表式で発生したターゲットコードは互いに反発し、exp 1を生成したらexp 2は存在しない.簡単な例を以下に挙げます.
int main(void)
{
    (void)__builtin_choose_expr(100 < 1000, puts("OK"), puts("NG"));

    int a = __builtin_choose_expr(sizeof('a') == 1, "YES", 100);
    printf("The value is: %d
", a); }
それから、コンパイルする時の内建関数を見ます.builting.types_comptiblep,その原型は――
int __builtin_types_compatible_p (type1, type2)
この関数は、type 1とtype 2のタイプを比較します.ここでは、式ではなくタイプです.2つのタイプの非限定バージョンが互換されている場合、1を返します.そうでなければ、0を返します.ここでは簡単な例を挙げます.
int main(void)
{
    int r = __builtin_types_compatible_p(typeof('a'), char);
    printf("result 1 is: %d
", r); r = __builtin_types_compatible_p(typeof('a'), const int); printf("result 2 is: %d
", r); }
はい.この二つのコンパイルを終えたら、C 11 Generanic Selectionの機能を実現するために、どのようにそれらを組み合わせるかを見てみましょう.
int main(void)
{
    _Generic('a', int:puts("WOW"), char:puts("Ja~~"), default:puts("Oui~~"));

    // equivalent
    (void)__builtin_choose_expr(__builtin_types_compatible_p(typeof('a'), int), puts("WOW"),
                                __builtin_choose_expr(__builtin_types_compatible_p(typeof('a'), char), puts("Ja~~"), puts("Oui~~")));
}
 
ここで注意したいのは、これらのビルド関数を使用するとGNU仕様がオンになり、4.7以上のバージョンのGCCは直接C 11規格を使用することができます.オープン方法は、コマンドオプションに-std=gnu 11を追加することです.