1. 程式人生 > >利用宏定義在編譯階段檢查結構體大小的方法

利用宏定義在編譯階段檢查結構體大小的方法

char tip return ati 內存 main color 個數 預編譯

typedef struct  
{  
    char a[100];  
} T_XXX;  
  
typedef struct  
{  
    char a[99];  
} T_QQQ;  
  
   
  
/* 檢測結構體的大小是否等於特定值 */  
#define    SIZE_OF_TYPE_EQUAL_TO(type, size) \  
static inline char size_of_##type##_equal_to_##size() \  
{ \  
    char __dummy1[sizeof(type) - size]; \  
    char
__dummy2[size - sizeof(type)]; \ return __dummy1[-1] + __dummy2[-1]; \ } /* 檢測結構體的大小是否不等於特定值 */ #define SIZE_OF_TYPE_UNEQUAL_TO(type, size) \ static inline char size_of_##type##_unequal_to_##size() \ { \ char __dummy1[0==(10/(sizeof(type)-size))]; \ return __dummy1[-1
]; \ } /* 檢測結構體的大小是否不大於特定值 */ #define SIZE_OF_TYPE_NOT_LARGER_THAN(type, size) \ static inline char size_of_##type##_not_larger_than_##size() \ { \ char __dummy1[size - sizeof(type)]; \ return __dummy1[-1]; \ } /* 檢測結構體的大小是否不小於特定值 */ #define SIZE_OF_TYPE_NOT_SMALLER_THAN(type, size) \ static
inline char size_of_##type##_not_smaller_than_##size() \ { \ char __dummy1[sizeof(type) - size]; \ return __dummy1[-1]; \ } /* 檢測結構體的大小是否小於特定值 */ #define SIZE_OF_TYPE_SMALLER_THAN(type, size) \ SIZE_OF_TYPE_NOT_LARGER_THAN(type, size) \ SIZE_OF_TYPE_UNEQUAL_TO(type, size) /* 檢測結構體的大小是否大於特定值 */ #define SIZE_OF_TYPE_LARGER_THAN(type, size) \ SIZE_OF_TYPE_NOT_SMALLER_THAN(type, size) \ SIZE_OF_TYPE_UNEQUAL_TO(type, size) /* 檢測結構體的大小是否小於特定值 版本2 */ #define SIZE_OF_TYPE_SMALLER_THAN2(type, size) \ static inline char size_of_##type##_smaller_than2_##size() \ { \ char __dummy1[size - sizeof(type) - 1]; \ return __dummy1[-1]; \ } /* 檢測結構體的大小是否大於特定值 版本2 */ #define SIZE_OF_TYPE_LARGER_THAN2(type, size) \ static inline char size_of_##type##_larger_than2_##size() \ { \ char __dummy1[sizeof(type) - size - 1]; \ return __dummy1[-1]; \ } /* 檢測結構體的大小是否為特定值的整數倍 */ #define SIZE_OF_TYPE_IS_MULTIPLE_OF(type, size) \ static inline char size_of_##type##_is_multiple_of_##size() \ { \ char __dummy1[0 - (sizeof(type) % size)]; \ return __dummy1[-1]; \ } /*** 好了,現在開始,想檢查什麽,調用相應的宏即可。 如果結構大小不符合要求,則會編譯出錯。 註意,對宏的調用,不要寫在任何函數內 :-) ***/ SIZE_OF_TYPE_EQUAL_TO(T_XXX, 100) SIZE_OF_TYPE_UNEQUAL_TO(T_XXX, 99) SIZE_OF_TYPE_NOT_LARGER_THAN(T_XXX, 100) SIZE_OF_TYPE_NOT_SMALLER_THAN(T_QQQ, 98) SIZE_OF_TYPE_LARGER_THAN(T_QQQ, 96) SIZE_OF_TYPE_SMALLER_THAN(T_QQQ, 200) SIZE_OF_TYPE_LARGER_THAN2(T_QQQ, 96) SIZE_OF_TYPE_SMALLER_THAN2(T_QQQ, 200) SIZE_OF_TYPE_IS_MULTIPLE_OF(T_QQQ, 9) int main() { return 0; }

SIZE_OF_TYPE_EQUAL_TO(type, size):
如果type != size,那麽__dummy1 ,__dummy2這2個數組在定義時肯定有一個是負數,數組在分配大小時會將大小視為無符號型處理,那麽此時這個數組的大小將會變得很大,例如-1是0xFFFFFFFF(32位機上),數組存在的位置要麽是堆棧 char a[5];要麽是代碼段chara[5] = {0}; 而堆棧,內存大小總有限制,所以預編譯器會檢查,並報錯。

SIZE_OF_TYPE_UNEQUAL_TO(type, size):
如果2者相等,10/(sizeof(type)-size) 這個算數運算就會報錯,0作除數了。

其他實現方法都采用了類似的原理。

利用宏定義在編譯階段檢查結構體大小的方法