[英]Checking types of macro parameters at compile time
為了檢查兩個變量具有相同的結構類型,我使用了一個宏
#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的可能性會很有趣。
#define ASSERT_SAME_TYPE(a, b) ((void) (&(a) == &(b)))
將為您提供編譯診斷和-Werror
錯誤(對於gcc
或其他編譯器的類似選項)。
請注意,許多編譯器都具有非標准擴展名typeof
運算符,用於獲取對象的類型,這可用於檢查兩種類型是否相同。
這個問題詢問有關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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.