// 统计变参数量
#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. X2加密的PcbDoc类型导出内容有误,不加密的PcbDoc导出的表格正常

    出现该类问题说明读取PcbDoc文件文件出了文件,加密类型添加tmp类型即可

  2. ios上架流程 详细通关教程 2021

    记录此文是源于以下需求 1.已有app store开发者账号 (公司账号$99),需上架至app store 2.有商城实体商品支付功能(会员等虚拟支付另说) 3.有硬件交互功能 注:建议预留一周上架 ...

  3. 牛客刷Java记录第6天

    第一题 一个文件中的字符要写到另一个文件中,首先需要( ). A System.out.print (buffer[i]); B FileOutputStream fout = new FileOut ...

  4. MinIO客户端之rm

    MinIO提供了一个命令行程序mc用于协助用户完成日常的维护.管理类工作. 官方资料 mc rm 删除指定的对象. 准备待删除的对象,查看对象,命令如下: ./mc ls local1/bkt2/ 控 ...

  5. 【开源项目推荐】Great Expectations—开源的数据质量工具

    大家好,我是独孤风. 又到了本周的开源项目推荐.数据质量是企业进行数据治理非常重要的一个环节,高质量的数据对管理决策,业务支撑都有非常重要的作用. 只有持续的数据质量改进才能推动数据治理体系的完善,差 ...

  6. 使用Bot Framework建立你的第一个聊天机器人

    今天微软给我推送了一个邮件,大概是微软近期开发了很多人工智能相关的API,无意中看到了Bot Framework,就点进去看了看似乎还蛮有意思的.于是准备搭建一个环境试试. 第一步需要下载Bot Ap ...

  7. Java 获取Excel中的表单控件

    Excel中可通过[开发工具]菜单栏下插入表单控件,如文本框.单选按钮.复选框.组合框等等,插入后的控件可执行设置控件格式,如大小.是否锁定.位置.可选文字.数据源区域.单元格链接等.当Excel中已 ...

  8. 神经网络基础篇:关于 python_numpy 向量的说明(A note on python or numpy vectors)

    关于 python_numpy 向量的说明 主要讲Python中的numpy一维数组的特性,以及与行向量或列向量的区别.并说一下在实际应用中的一些小技巧,去避免在coding中由于这些特性而导致的bu ...

  9. 华为云云容器引擎CCE产品文档带来4个升级,降低使用难度

    本文分享自华为云社区<华为云云容器引擎CCE产品文档优化升级!>,作者: 云容器大未来 . 云原生产品技术栈庞大,需要用户对容器.Kubernetes等核心技术都有扎实的理解和掌握:同时问 ...

  10. “pip不是内部或外部命令,也不是可运行的程序或批处理文件” 到底有多么神秘

    摘要:pip不是内部或外部命令,也不是可运行的程序或批处理文件到底有多么神秘? 本文分享自华为云社区<揭开「pip不是内部或外部命令,也不是可运行的程序或批处理文件」的神秘面纱>,作者:A ...