13
FUNC(param);

でしたら、着払いparamchar *発送致しfunc_stringます。

の場合int、発送先func_int

変数の型はコンパイル時に認識されるため、これに対する解決策があると思います..

4

7 に答える 7

16

これはC1Xでは可能ですが、現在の標準では不可能です。

次のようになります。

#define cbrt(X) _Generic((X), long double: cbrtl, \
                          default: cbrt, \
                          float: cbrtf)(X)
于 2011-08-31T11:24:41.947 に答える
11

変数の型はコンパイラには認識されますが、プリプロセッサには認識されません (コードを単純に非構造化テキストトークンのストリームとして認識し、単純な置換操作のみを実行します)。したがって、C マクロではこれを実現できないと思います。

C++ では、このような問題 (およびそれ以上) を解決するためのテンプレートが発明されました。

于 2011-08-31T11:23:50.453 に答える
6

タイプの特性をテストできます。

たとえばint、負の値を保持できますが、保持char*できません。したがって((typeof(param))-1) < 0paramが署名されていない場合:

if (((typeof(param))-1) < 0) {
    do_something_with_int();
} else {
    do_something_with_char_p();
}

コンパイラは明らかにこれを最適化します。

ここで試してみてください: http://ideone.com/et0v1

タイプのサイズが異なる場合、これはさらに簡単になります。たとえば、さまざまな文字サイズを処理できる汎用マクロを作成する場合は、次のようにします。

if (sizeof(param) == sizeof(char)) {
    /* ... */
} else if (sizeof(param) == sizeof(char16_t)) {
    /* ... */
} else if (sizeof(param) == sizeof(char32_t)) {
    /* ... */
} else {
   assert("incompatible type" && 0);
}

GCC には、__builtin_types_compatible_p()型の互換性をチェックできる組み込み関数があります。

if (__builtin_types_compatible_p(typeof(param), int)) {
    func_int(param);
} else if (__builtin_types_compatible_p(typeof(param), char*)) {
    func_string(param);
}

ここで試してみてください: http://ideone.com/lEmYE

これをマクロに入れて、やろうとしていることを達成できます。

#define FUNC(param) ({                                                \
    if (__builtin_types_compatible_p(typeof(param), int)) {           \
        func_int(param);                                              \
    } else if (__builtin_types_compatible_p(typeof(param), char*)) {  \
        func_string(param);                                           \
    }                                                                 \
})

(これ({...})GCC のステートメント式であり、ステートメントのグループを右辺値にすることができます。

ビルトインは、__builtin_choose_expr()コンパイルする式を選択できます。__builtin_types_compatible_p を使用すると、param のタイプが と : の両方intと互換性がない場合、コンパイル時にエラーをトリガーできますchar*(この場合、無効なものをコンパイルすることにより)

#define FUNC(param)                                                        \ 
    __builtin_choose_expr(__builtin_types_compatible_p(typeof(param), int) \ 
        , func_int(param)                                                  \ 
        , __builtin_choose_expr(__builtin_types_compatible_p(typeof(param), char*) \ 
            , func_string(param)                                           \ 
            , /* The void expression results in a compile-time error       \ 
                 when assigning the result to something.  */               \ 
            ((void)0)                                                      \ 
        )                                                                  \ 
    )

これは実際には__builtin_choose_expr docsからわずかに変更された例です。

于 2011-08-31T11:48:06.817 に答える
4

C89 / ANSI C でタイム チェック タイプを実行する可能性はありませんが、それを可能にする gcc の拡張機能があります。私が覚えていれば、typeofまたはそれらの線に沿った何か。Linuxカーネルで一度見ました。

kernel.hで:

#define min(x, y) ({                \
typeof(x) _min1 = (x);          \
typeof(y) _min2 = (y);          \
(void) (&_min1 == &_min2);      \
_min1 < _min2 ? _min1 : _min2; })

この記事をご覧ください: Linux カーネルでの GCC ハック

私がこれを最初に見たとき、私は実際にここでSOについて質問しました:

kernel.h の min マクロ

問題を解決するためにどのように使用するのか正確にはわかりませんが、一見の価値があります。

于 2011-08-31T11:25:05.283 に答える
1

変数の型は確かにコンパイル時に認識されますが、マクロ展開はコンパイル前に行われます。マクロの代わりに 2 つのオーバーロードされた関数を実装することをお勧めします。

于 2011-08-31T11:25:11.150 に答える
1

これはマクロではできません。マクロの値はコンパイル時に置き換えられ、解釈されません。それらは単なる代替品です。

于 2011-08-31T11:24:20.527 に答える