【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 ...
随机推荐
- HOLMES通过关联可疑信息流进行实时 APT 检测
HOLMES 通过关联可疑信息流进行实时 APT 检测 基本信息 题目:HOLMES: Real-time APT Detection through Correlation of Suspiciou ...
- 数字孪生为何开始逐渐与GIS进行融合?
近年来,数字孪生技术和地理信息系统(GIS)在各自领域的快速发展引起了广泛关注.这两个技术的结合被认为是一种强大的联合,可以为各行各业带来革命性的变革和创新.那么,为何数字孪生开始逐渐与GIS进行融合 ...
- mysql的CRUD操作实现
插入语句(INSERT):一旦我们选择了要插入的字段, 我们就必须保证要插入的数值和选择的字段的个数,顺序,类型一致. 1:怎么插入一条数据: INSERT INTO 插入的表名称(列名1,列 ...
- 序列化性能测试:jdk和fastjson
序列化性能测试:jdk和fastjson 我开发一个认证授权框架时,需要添加数据库存储token或者会话,于是想测试使用jdk的blob存储解析快还是存储string的json序列化解析快,从而选择他 ...
- JAVA17安装体验JFX17抢先体验
JAVA17安装体验JFX17抢先体验 java17版本是长期支持版,至少更新5年以上.而且商用免费!这里我就来体验一把. 一.下载配置 java 17 官网下载地址:https://www.orac ...
- Java 并发编程(三)锁与 AQS
本文 JDK 对应的版本为 JDK 13 由于传统的 synchronized 关键字提供的内置锁存在的一些缺点,自 JDK 1.5 开始提供了 Lock 接口来提供内置锁不具备的功能.显式锁的出现不 ...
- MySQL进阶篇:详解索引结构
2.2 MySQL进阶篇:第二章_二.二_索引结构 2.2.1 概述 MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,主要包含以下几种: 索引结构 描述 B+Tree索引 最常见 ...
- 想会用synchronized锁,先掌握底层核心原理
摘要:synchronized锁修饰方法和代码块时底层实现上是一样的,但是在修饰方法时,不需要JVM编译出的字节码完成加锁操作,而synchronized在修饰代码块时,是通过编译出来的字节码生成的m ...
- 如何利用CANN DVPP进行图片的等比例缩放?
摘要:介绍如何用昇腾AI处理器上的DVPP单元进行,图像的等比例缩放,保证图像不变形. 本文分享自华为云社区<CANN DVPP进行图片的等比例缩放>,作者:马城林 . 1. 为什么需要进 ...
- 提升源代码安全性的C#和Java深度混淆工具——IpaGuard
提升源代码安全性的C#和Java深度混淆工具--IpaGuard 摘要 Ipa Guard是一款功能强大的IPA混淆工具,通过对iOS IPA文件进行混淆加密,保护其代码.资源和配置文件,降低破解反编 ...