2

2 つの変数の構造型が同じであることを確認するには、マクロを使用します

#define assert_same_struct_types(a, b)    ((void) (sizeof((a)=(b))))

関数のようなマクロの場合

#define m(a,b) blablabla

a と b が同じ構造体型であると仮定して、コンパイル時のチェックを追加します。

#define m(a,b) (assert_same_struct_types(a, b), blablabla)

m(a,b) の呼び出し元が誤って m に異なるタイプの構造体を渡すと、コンパイラ エラーが発生します。

ただし、このアプローチは、組み込み型とポインター型の間で暗黙的な変換が行われるため、常に機能するとは限りません。

では、必ずしも構造体ではなく、任意の型についてこの問題を解決することは可能ですか?

C89 の解決策が必要ですが、C99 または C11 の可能性について聞くのは興味深いことです。

4

2 に答える 2

4
#define ASSERT_SAME_TYPE(a, b)  ((void) (&(a) == &(b)))

コンパイル診断とエラーが表示されます-Werror( forgccまたは他のコンパイラの同様のオプション)。

多くのコンパイラにはtypeof、オブジェクトの型を取得するための非標準拡張演算子があり、これを使用して 2 つの型が同じであることを確認できることに注意してください。

于 2012-07-12T10:20:23.263 に答える
1

この質問では、C89 ソリューションについて尋ねます。これまでのところ、これを行う良い方法が見つかりませんでした。そのため、C89 に依存する代わりに、コンパイラがサポートしているかどうかを確認しtypeof、利用可能な場合はそれを使用できます。理想的ではありませんが、一部の開発者が GCC/Clang/IntelC を使用している限り、エラーがキャッチされることを意味します。もちろん、コンパイラに C89 のみをサポートするように指示した場合、これは役に立ちません。

より良い型チェックを提供しますが、サポートされていない場合はまったく役に立たないことは明らかです。

#ifdef __GNUC__
#define CHECK_TYPE(var, type)  {  \
    typeof(var) *__tmp;           \
    __tmp = (type *)NULL;         \
    (void)__tmp;                  \
} (void)0

#define CHECK_TYPE_PAIR(var_a, var_b)  {  \
    typeof(var_a) *__tmp;                 \
    __tmp = (typeof(var_b) *)NULL;        \
    (void)__tmp;                          \
} (void)0

#define CHECK_TYPE_PAIR_INLINE(var_a, var_b)  ((void)({  \
    typeof(var_a) *__tmp;                                \
    __tmp = (typeof(var_b) *)NULL;                       \
    (void)__tmp;                                         \
}))

#else
#  define CHECK_TYPE(var, type)
#  define CHECK_TYPE_PAIR(var_a, var_b)
#  define CHECK_TYPE_PAIR_INLINE(var_a, var_b) (void)0
#endif

/* inline type checking - can mix in with other macros more easily using the comma operator,
 * C11 gives best results here */
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
#  define CHECK_TYPE_INLINE(val, type) \
    (void)((void)(((type)0) != (0 ? (val) : ((type)0))), \
           _Generic((val), type: 0, const type: 0))
#else
#  define CHECK_TYPE_INLINE(val, type) \
    ((void)(((type)0) != (0 ? (val) : ((type)0))))
#endif
于 2014-09-24T02:06:48.203 に答える