// 统计变参数量
#define CALC_VA_COUNT(arg...) \
({ \
int count = 0; \
int insideQuotes = 0; \
const char *str = #arg; \
printf("D> CALC_VA_COUNT: %s\n", str); \
while (*str != '\0') { \
if (*str == '"') { \
insideQuotes = !insideQuotes; \
} else if (*str == ',' && !insideQuotes) { \
count++; \
} \
str++; \
} \
++count; \
})
// 变参数量多于1个,则生效最后1个(逗号表达式)
#define CHECK(expr, ...) \
do { \
if (!(expr)) { \
printf("check fail: \"%s\" @ %s, %u\r\n", #expr, __FILE__, __LINE__); \
return __VA_ARGS__; \
} \
} while(0)
#define ASSERT(expr)    (void)((!!(expr)) || (printf("assert fail: \"%s\" @ %s, %u", #expr, __FILE__, __LINE__), printf("\r\n")))
// usage:
ASSERT(arg != NULL) #define ASSERT(expr) (void)((!!(expr)) && (printf("assert fail: \"%s\" @ %s, %u", #expr, __FILE__, __LINE__), printf("\r\n")))
// usage:
ASSERT(arg == NULL) #define ASSERT(expr) (int)((!!(expr)) || (printf("assert fail: \"%s\" @ %s, %u", #expr, __FILE__, __LINE__), printf("\r\n"), Abort()))
// usage:
if (!ASSERT(arg != NULL)) {
return;
} #define ASSERT(expr) (int)((!!(expr)) && (printf("assert fail: \"%s\" @ %s, %u", #expr, __FILE__, __LINE__), printf("\r\n"), Abort()))
// usage:
if (!ASSERT(arg == NULL)) {
return;
}
int Abort(void)
{
printf("reset reboot!\n");
// 处理异常代码
}

示例:

// Powered by skull
#include <stdio.h> #define CALC_VA_COUNT(arg...) \
({ \
int count = 0; \
int insideQuotes = 0; \
const char *str = #arg; \
printf("D> CALC_VA_COUNT: %s\n", str); \
while (*str != '\0') { \
if (*str == '"') { \
insideQuotes = !insideQuotes; \
} else if (*str == ',' && !insideQuotes) { \
count++; \
} \
str++; \
} \
++count; \
}) #define CHECK(expr, ...) \
do { \
if (!(expr)) { \
printf("I> check fail: \"%s\" @ %s, %u\r\n", #expr, __FILE__, __LINE__); \
printf("D> __VA_ARGS__: %s\r\n", #__VA_ARGS__); \
if (CALC_VA_COUNT(__VA_ARGS__) > 1) printf("W> too many parameters. last effective!\r\n"); \
return __VA_ARGS__; \
} \
} while(0) #define ASSERT1(expr) (void)((!!(expr)) || (printf("A> assert fail: \"%s\" @ %s, %u", #expr, __FILE__, __LINE__), printf("\r\n")))
#define ASSERT2(expr) (void)((!!(expr)) && (printf("A> assert fail: \"%s\" @ %s, %u", #expr, __FILE__, __LINE__), printf("\r\n")))
#define ASSERT3(expr) (int)((!!(expr)) || (printf("A> assert fail: \"%s\" @ %s, %u", #expr, __FILE__, __LINE__), printf("\r\n"), Abort1()))
#define ASSERT4(expr) (int)((!!(expr)) && (printf("A> assert fail: \"%s\" @ %s, %u", #expr, __FILE__, __LINE__), printf("\r\n"), Abort2())) int Abort1(void)
{
printf("reset reboot!\n");
// 异常处理
} int Abort2(void)
{
printf("reset reboot!\n");
// 异常处理
return -1;
} void test_assert(void *pointer)
{
ASSERT1(pointer != NULL);
ASSERT2(pointer == NULL);
if (ASSERT3(pointer != NULL)) {
printf("ASSERT3\n");
}
if (!ASSERT3(pointer != NULL)) {
printf("!ASSERT3\n");
}
if (ASSERT4(pointer == NULL)) {
printf("ASSERT4\n");
}
if (!ASSERT4(pointer == NULL)) {
printf("!ASSERT4\n");
}
} void test_check(void *pointer)
{
CHECK(pointer == NULL);
printf("check @%s\n", __func__);
} void test_check1(void *pointer)
{
CHECK(pointer != NULL);
printf("check @%s\n", __func__);
} char *test_check2(void *pointer)
{
CHECK(pointer != NULL, "check fail!");
printf("check @%s\n", __func__);
} char *test_check3(void *pointer)
{
CHECK(pointer != NULL, "check fail!", __func__);
printf("check @%s\n", __func__);
} int main(void)
{
int *arg;
printf("Hello Assert!\n");
test_assert(arg);
printf("Hello check!\n");
test_check(arg);
test_check1(arg);
printf("check result: %s\n", test_check2(arg));
printf("check result: %s\n", test_check3(arg));
return 0;
}

【C/C++】函数入参检查的更多相关文章

  1. js的replace函数入参为function时的疑问

    近期在写js导出excel文件时运用到replace方法,此处详细的记录下它各个参数所代表的的意义. 定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式 ...

  2. C语言函数入参压栈顺序为什么是从右向左?

    看到有人提问到,在处理printf/cout时,压栈顺序是什么样的?大家都知道是从右往左,也就是说从右往左的计算,但是,这里的计算不等于输出. a++和++a的压栈的区别:在计算时,遇到a++会记录此 ...

  3. python函数入参和返回值

    以下内容参考自runoob网站,以总结python函数知识点,巩固基础知识,特此鸣谢! 原文地址:http://www.runoob.com/python3/python3-function.html ...

  4. oracle常用函数以及调用入参为record的存储过程的方法,

    转自:http://www.cnblogs.com/zhangronghua/archive/2007/08/20/862812.html SQL中的单记录函数1.ASCII返回与指定的字符对应的十进 ...

  5. python学习笔记(九)函数返回多个值,列表生成式,循环多个变量,入参格式声明

    一.函数返回多个值 1.函数如果返回多个值的话,它会把这几个值放到一个元组里面2.函数如果返回多个值的话,也可以用多个变量来接收 def say(): num1 = num2 = num3 = ret ...

  6. c++调用python系列(1): 结构体作为入参及返回结构体

    最近在打算用python作测试用例以便对游戏服务器进行功能测试以及压力测试; 因为服务器是用c++写的,采用的TCP协议,当前的架构是打算用python构造结构体,传送给c++层进行socket发送给 ...

  7. 悉数 Python 函数传参的语法糖

    TIOBE排行榜是程序开发语言的流行使用程度的有效指标,对世界范围内开发语言的走势具有重要参考意义.随着数据挖掘.机器学习和人工智能相关概念的风行,Python一举收获2018年年度语言,这也是Pyt ...

  8. C#构造函数在继承时必须要求与父类型构造函数入参相同怎么办?

    摘要 我们都知道,C#中,在类型继承时,由于构造子类必须先构造其父类型的内容,因此,必须子类型的构造函数中调用父类型的构造函数(无参数的不需要显式声明). 但是往往我们会出现,子类型本身的构造函数大于 ...

  9. @ModelAttribute 注解及 POJO入参过程

    一.modelattribute注解 @ModelAttribute注解的方法有两种,一种无返回值,一种有返回值,方法的可以用@RequestParam注解来获取请求的参数,如果不获取参数,可以不用此 ...

  10. Saiku根据入参日期查询出对应的数据(二十)

    Saiku根据入参日期查询出对应的数据 之前好像有写过一篇博客关于saiku date range的,现在进一步更新啦!!! 这里的日期筛选会更完善一些,需要提供两个参数 开始日期与结束日期(star ...

随机推荐

  1. 解决 VM with version 2.1.0 has multidex support ; VM has multidex support, MultiDex support library is disabled.问题

    发布打包完之后,android studio提示 VM with version 2.1.0 has multidex support I/MultiDex: installI/MultiDex: V ...

  2. NC65单据模板公式使用

    单据模板公式使用 (一) 公式使用场景 用户使用产品时,往往对单据上的字段取值有各种不同的需求.为此单据模板提供 了模板公式功能,可以让实施顾问或者用户通过配置各种公式,并且不用修改代码,从 而满足用 ...

  3. shopify主题模板速度优化

    前两天一位新客户说他的shopify店铺加载速度很慢,首页完全加载需要 5~6 秒甚至更高,问ytkah有没办法帮忙优化一下.shopify网站速度优化要看具体用了什么模板,有什么功能,哪些可以改哪些 ...

  4. cgroup的入门资料

    近期在准备特性的设计文档,按照评审专家的建议,需要排查现有产品中算力资源比如CPU.内存的分配方案,确认现有的硬件款型是否具备充足的资源来启用本特性. 依据前辈提供的建议,检查了产品的部署脚本,发现当 ...

  5. markdown中插入视频前台渲染出来导致<video>等标签被转义成字符

    markdown中插入视频前台渲染出来导致<video>等标签被转义成字符解决办法: 如图: 在markdown里面插入视频,可以按照下面写法,哈哈,虽然很捞,但是还是可以满足的. < ...

  6. Base64编码:数据传输的安全使者

    Base64编码是一种将二进制数据转换为可传输的文本表示形式的方法,它在全球范围内被广泛应用于网络通信.数据存储和传输等领域.本文将从多个方面介绍Base64编码的原理.应用及其在现实场景中的优势,帮 ...

  7. Git使用经验总结2-配置用户名邮箱

    可以使用git config指令来配置一些设置,比如配置用户名邮箱.在开发团队要求成员配置用户名和邮箱是很有用的,可以配合工具区分成员的代码,以及将代码中的问题发送给成员的邮箱中. 查看当前Git的用 ...

  8. MySQL数据库技术与应用:数据查询

    摘要:数据查询是数据库系统应用的主要内容,也是用户对数据库最频繁.最常见的基本操作请求. 数据查询 数据查询是数据库系统应用的主要内容,也是用户对数据库最频繁.最常见的基本操作请求.数据查询可以根据用 ...

  9. 18篇文章系统解读:中台规划如何撬动企业IT基础设施转型升级

    摘要:通过这个系列,让大家对中台的价值.针对的问题痛点.中台规划的方法思路和技巧.一些中台业务实践有个基本的认识,让客户清楚的意识到企业中台的业务价值,进而通过企业中台规划牵引客户IT基础设施投资. ...

  10. 详解NLP和时序预测的相似性【附赠AAAI21最佳论文INFORMER的详细解析】

    摘要:本文主要分析自然语言处理和时序预测的相似性,并介绍Informer的创新点. 前言 时序预测模型无外乎RNN(LSTM, GRU)以及现在非常火的Transformer.这些时序神经网络模型的主 ...