要检查两个变量是否具有相同的结构类型,我使用宏
#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的可能性会很有趣。
答案 0 :(得分:3)
#define ASSERT_SAME_TYPE(a, b) ((void) (&(a) == &(b)))
将使用-Werror
(gcc
或其他编译器的类似选项)为您提供编译诊断和错误。
请注意,许多编译器都有一个非标准的扩展typeof
运算符来获取对象的类型,这可以用来检查两种类型是否相同。
答案 1 :(得分: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