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

http://blog.csdn.net/crazycoder8848/article/details/8292770


=====================================================



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;
}



转载于:https://www.cnblogs.com/iplus/archive/2013/04/07/4467305.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/408972.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

剑指offer--在O(1)时间内删除链表结点

记录来自《剑指offer》上的算法题。 题目如下: 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。 结点定义如下: struct ListNode{int m_nValue;ListNode* m_pNext; }; 最常规的删除链表结点方法是从头结点开始遍历…

Designer设计无代码工作流

1. 打开Designer,选择工作流,选择列表工作流,选择你要将此工作流应用的列表(这里我选择报销单)。 填写好工作流名称,点击确定。 现在我们开始正式设计工作流,首先我们拉一个记录历史到工作流中&…

剑指offer--调整数组顺序使奇数位于偶数前面

记录来自《剑指offer》的算法题。 题目如下: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。 最简单的思路就是从头开始扫描整个数组,当碰到偶…

java proguard 使用_使用proguard混淆java9代码

序本文主要研究一下如何使用proguard混淆java9代码mavencom.github.wvengenproguard-maven-pluginpackageproguard6.0.1${project.build.finalName}.jar${project.build.finalName}.jar!META-INF/maven/**,!module-info.classtrue${project.basedir}/proguard.cfg${java.home}/…

75个移动App开发教程

原文地址:http://www.goodfav.com/zh/app-development-tutorials-3559.html 移动应用程序开发是大企业和创意的个人和小团队开发,是一个有很多商业机会的领域之一。它可能需要多次尝试设计来实施一个出类拔萃的应用程序,但是,如果…

机器学习算法总结--线性回归和逻辑回归

1. 线性回归 简述 在统计学中,线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合(自变量都…

java 对应sql驱动版本_关于Oracle JDBC驱动版本、JDK版本、数据库版本对应关系(相关的报错:ORA-28040)...

关于Oracle JDBC驱动版本、JDK版本、数据库版本对应关系说明:1、Oracle JDBC驱动版本查看方式(Oracle JDBC驱动程序随Oracle数据库服务器一起提供)(用户:Oracle”);$cd $ORACLE_HOME/jdbc/libojdbc5.jarojdbc6.jar2、JDK版本查看方式&#xf…

Thinking in java之前

开始写博客了,从哪里开始呢,因为是抱着学习的态度开始写,所以选择用java开始。很多人说C语言是最适合入门的语言,不知道为什么,我却一直觉得java是入门语言首选。 java是简单的,健壮的,灵活的。…

C++知识总结(1)--变量和基本类型

最近打算看看《C primer》,重新复习C的一些知识点,同时会添加部分在做牛客网编程题目时候记录的知识点。 变量和基本类型 endl操纵符的效果是结束当前行,并将与设备关联的缓冲区中的内容刷到设备中。缓冲刷新操作可以保证到目前为止程序所产…

coroutine php_PHP 协程实现

多进程/线程最早的服务器端程序都是通过多进程、多线程来解决并发IO的问题。进程模型出现的最早,从Unix 系统诞生就开始有了进程的概念。最早的服务器端程序一般都是 Accept 一个客户端连接就创建一个进程,然后子进程进入循环同步阻塞地与客户端连接进行…

ORACLE PL/SQL编程之八: 把触发器说透

本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 触发器触发次序 8.2.2 创建DML触发器 8.2.3 创建替代(INSTEAD OF)触发器 8.2.3 创建系统事件触发器 8.2.4 系统触发器事件属性 8.2.5 使用触发器谓词 8.…

机器学习算法总结--决策树

简介 定义:分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点和有向边组成。结点有两种类型:内部结点和叶结点。内部结点表示一个特征或属性,叶结点表示一个类。 决策树学习通常包括3个步骤:特征选择、决策树的生…

mac终端查看php版本_Mac切换php版本方法

本文主要和大家分享Mac切换php版本方法,希望能帮助到大家。1.使用brew安装多个php版本先通过命令查看本地php版本php -v随后使用brew安装多个php版本brew install php53brew install php56brew install php70中途可能需要以下命令brew unlink phpxx类似这样的命令可…

PAT_1007(中文)_素数对猜想

题目地址&#xff1a;http://pat.zju.edu.cn/contests/pat-b-practise/1007 1 #include<stdio.h>2 #include<math.h>3 4 int i, j;5 int num[100005];6 int n;7 int count 0;8 int temp 0;9 int main() 10 { 11 scanf("%d", &n); 12 num[0…