【C/C++】函数入参检查
// 统计变参数量
#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++】函数入参检查的更多相关文章
- js的replace函数入参为function时的疑问
近期在写js导出excel文件时运用到replace方法,此处详细的记录下它各个参数所代表的的意义. 定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式 ...
- C语言函数入参压栈顺序为什么是从右向左?
看到有人提问到,在处理printf/cout时,压栈顺序是什么样的?大家都知道是从右往左,也就是说从右往左的计算,但是,这里的计算不等于输出. a++和++a的压栈的区别:在计算时,遇到a++会记录此 ...
- python函数入参和返回值
以下内容参考自runoob网站,以总结python函数知识点,巩固基础知识,特此鸣谢! 原文地址:http://www.runoob.com/python3/python3-function.html ...
- oracle常用函数以及调用入参为record的存储过程的方法,
转自:http://www.cnblogs.com/zhangronghua/archive/2007/08/20/862812.html SQL中的单记录函数1.ASCII返回与指定的字符对应的十进 ...
- python学习笔记(九)函数返回多个值,列表生成式,循环多个变量,入参格式声明
一.函数返回多个值 1.函数如果返回多个值的话,它会把这几个值放到一个元组里面2.函数如果返回多个值的话,也可以用多个变量来接收 def say(): num1 = num2 = num3 = ret ...
- c++调用python系列(1): 结构体作为入参及返回结构体
最近在打算用python作测试用例以便对游戏服务器进行功能测试以及压力测试; 因为服务器是用c++写的,采用的TCP协议,当前的架构是打算用python构造结构体,传送给c++层进行socket发送给 ...
- 悉数 Python 函数传参的语法糖
TIOBE排行榜是程序开发语言的流行使用程度的有效指标,对世界范围内开发语言的走势具有重要参考意义.随着数据挖掘.机器学习和人工智能相关概念的风行,Python一举收获2018年年度语言,这也是Pyt ...
- C#构造函数在继承时必须要求与父类型构造函数入参相同怎么办?
摘要 我们都知道,C#中,在类型继承时,由于构造子类必须先构造其父类型的内容,因此,必须子类型的构造函数中调用父类型的构造函数(无参数的不需要显式声明). 但是往往我们会出现,子类型本身的构造函数大于 ...
- @ModelAttribute 注解及 POJO入参过程
一.modelattribute注解 @ModelAttribute注解的方法有两种,一种无返回值,一种有返回值,方法的可以用@RequestParam注解来获取请求的参数,如果不获取参数,可以不用此 ...
- Saiku根据入参日期查询出对应的数据(二十)
Saiku根据入参日期查询出对应的数据 之前好像有写过一篇博客关于saiku date range的,现在进一步更新啦!!! 这里的日期筛选会更完善一些,需要提供两个参数 开始日期与结束日期(star ...
随机推荐
- 华企盾DSC客户端图标不显示常见处理方法
1.检查是否启用了360桌面.猎豹桌面之类的(兼容腾讯桌面),打强制显示客户端图标的补丁 2.是否被杀毒软件查杀 3.用Autoruns查看explorer项图标那一栏前10个是否有我们图标没有的话把 ...
- pytest框架中conftest.py的作用
conftest.py 是 pytest 框架中的一个特殊文件.它允许你为测试提供自定义的配置和钩子函数.以下是 conftest.py 的主要作用: 提供全局配置:你可以在 conftest.py ...
- 放弃JavaFx开发学习
放弃JavaFx开发学习 一开始学学习JavaFx是想用java写个小游戏,后来学者JavaFx越来越深,发现坑也越来越多,不禁感叹:JavaFx果然是要抛弃的UI玩儿,UI开发还是用react na ...
- C++篇:第十四章_编程_知识点大全
C++篇为本人学C++时所做笔记(特别是疑难杂点),全是硬货,虽然看着枯燥但会让你收益颇丰,可用作学习C++的一大利器 十四.编程 (一)概念 系统函数及其库是 C++语言所必须的,预处理命令不是 C ...
- 基于k6和python进行自动化性能测试
摘要:在性能测试中,达到相应的性能指标对于一个软件来说十分重要,在本文中,将介绍一种现代化性能测试工具k6. 本文分享自华为云社区<基于k6和python进行自动化性能测试>,作者: 风做 ...
- 高性能利器!华为云MRS ClickHouse重磅推出!
摘要:华为智能数据湖MRS服务即将上线ClickHouse高性能引擎集群,用户只需要几分钟,就可以轻松方便地一键式完成集群部署搭建,快速拥有PB级数据的秒级交互查询分析能力,帮助用户带来极致的性能体验 ...
- MindSpore:不用摘口罩也知道你是谁
[本期推荐专题]从三大主流前端技术出发,看看它们各自特性,以及如何从业务特性出发,选择合适的框架. 摘要:我们基于MindSpore设计了一种人脸识别算法,以解决口罩遮挡场景下的人脸识别问题.该算法的 ...
- CWE4.6标准中加入 OWASP 2021 TOP10
摘要: 新发布的CWE4.6标准,加入了OWASP 2021 TOP10的视图. 本文分享自华为云社区<CWE 4.6 和 OWAPS TOP10(2021)>,作者: Uncle_Tom ...
- 万字长文|大数据学前准备之Linux入门笔记(附资料)
对于大数据学习而言,Linux运维可以说是必备的技能.可以不研究的过于高深,但是基本的操作和使用一定要熟练.Linux的学习需要大量的实践,本文从linux的基本知识,实战操作,到常用的指令与软件安装 ...
- 如何注册appuploader账号
如何注册appuploader账号 我们上一篇讲到appuploader的下载安装,要想使用此软件呢,需要注册账号才能使用,今 天我们来讲下如何注册appuploader账号来使用软件. 1.A ...