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)))

将为您提供编译诊断和错误-Werrorgcc对于其他编译器或类似选项)。

请注意,许多编译器都有一个非标准的扩展typeof运算符来获取对象的类型,这可用于检查两种类型是否相同。

于 2012-07-12T10:20:23.263 回答
1

这个问题询问了一个 C89 解决方案,到目前为止我还没有找到一个好的方法来做到这一点,所以你可以检查编译器是否支持typeof并在可用时使用它,而不是依赖 C89。它并不理想,但意味着只要一些开发人员使用 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 回答