簡體   English   中英

在編譯時檢查宏參數的類型

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM