利用宏定义在编译阶段检查结构体大小的方法

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作除数了。

其他实现方法都采用了类似的原理。

时间: 2024-08-28 04:49:11

利用宏定义在编译阶段检查结构体大小的方法的相关文章

c++ 编译时检测结构体大小的的宏定义写法

一种写法: template <bool> struct CompileAssert { }; #define COMPILE_ASSERT(expr, msg) \ typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] } //endof namespace 第二种写法: 1 #define CAT_TOKEN_1(t1,t2) t1##t2 2 #define CAT_TOKEN(t1,t2) CAT_TOKE

【转】彻底搞清计算结构体大小和数据对齐原则

彻底搞清计算结构体大小和数据对齐原则 数据对齐: 许多计算机系统对基本数据类型合法地址做出了一些限制,要求某种类型对象的地址必须是 某个值K(通常是2,4或8)的倍数.这种对齐限制简化了形成处理器和存储器系统之间的接口的硬件 设计.例如,假设一个处理器总是从存储器中取出8个字节,则地址必须为8的倍数.如果我们能保 证将所有的double类型数据的地址对齐成8的倍数,那么就可以用一个存储器操作来读或者写值了. 否则,我们可能需要执行两次存储器访问,因为对象可能被分放在两个8字节存储块中. 当数据类

结构体大小求值

 内存对齐概念,struct例子: struct stu{ char a; intb; char c; double d; char e; } 取pack(n),n,取结构体中最大成员大小m,取两个小值k, k = m< n?m:n; 取每个成员大小p,依次同k比较,取小值q = k< p?k:p; 第二步当中依次取得的值,即为内对齐标准,所谓的对齐,即此处的地址可被q整除. K值可作为外部对齐补0的依据. 当有数组的时候拆散了当普通变量存储. 下面开始计算结构体中的大小 取k值.(取pa

程序猿之---C语言细节29(#define宏大小、空结构体大小、柔性数组不知道你见过没)

主要内容:#define宏大小.空结构体大小.柔性数组 一.#define宏大小 见例子 二.空结构体大小 根编译器有关 三.柔性数组 不常用,可看看 #include <stdio.h> #define N 4 #define STR "abcd" int main() { struct student { }stu; printf("N = %d\n", sizeof(N)); printf("num 5 memery = %d\n&quo

C/C++ sizeof函数解析——解决sizeof求结构体大小的问题

C/C++中不同数据类型所占用的内存大小 32位                 64位 char               1                    1 int                  4             大多数4,少数8 short              2                    2 long               4                    8 float               4              

【c语言】结构体大小计算的例子

// 结构体大小计算的例子 // 默认对齐数为4 #include <stdio.h> union tagAAA { struct { char ucFirst;//1 short ucSecond;//2 char ucThird;//1 }half; short kk;//2 }number; struct tagBBB { char ucFirst;//1 short ucSecond;//2 char ucThird;//1 short ucForth;//2 }half; struc

关于C语言中结构体大小计算

结构体大小的计算,.网上说法一大堆还都不一样分什么对齐不对齐,偏移量什么的.. 在此稍微举例简单总结下: 对齐原则:每一成员的结束偏移量需对齐为后一成员类型的倍数 补齐原则:最终大小补齐为成员中最大值的倍数 拿个题目做例子:[(开始偏移量)+此处字节 = 结束偏移量] 1 struct MyStruct 2 { 3 int i; // (0) + 4 = 4,后面一个为2,已经对齐 4 char c; // (4) + 2 = 6,后面一个为结构体,直接拆开看第一个,int=4,所以对齐为(4)

结构体大小的计算以及内存对其原则和修改默认对齐数

1.结构体大小的计算 **我们都知道,不论是数组还是指针都可以计算其大小, 而同样结构体也是可以计算大小的, 接下来我们就深入讨论如何计算结构体的大小.** #include<stdio.h> #includ<stdlib.h> struct s1 { char c1; int a; char c2; }; int main() { printf("%d\n", sizeof(struct s1)); system("pause"); ret

结构体大小的计算方法

****************************************************************************************** 结构体大小的计算方法: 1.结构体成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍). 2.结构体大小必须是所有成员大小的整数倍. ***************************************************************************************