宏参数多对一:使用分号分隔多参数

宏部分替换:替换需要转换的再与后续宏接续

#include <stdio.h>

#define _MESS_FAILED()    printf("%s %d: ASSERT FAILED\r\n", __func__, __LINE__)
#define TU_BREAKPOINT() \
do { \
printf("TU_BREAKPOINT()\n"); \
} while (0) #define TU_VERIFY_DEFINE(_cond, _handler, _ret) \
do { \
if (!(_cond)) { \
_handler; \
return _ret; \
} \
} while(0) #define GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 // 宏参数多对一 ';'
#define ASSERT_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), false)
#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret) // 宏部分替换
#define TU_ASSERT(...) GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS, UNUSED)(__VA_ARGS__) typedef enum{false, true} bool; bool assert_function_true(void)
{
TU_ASSERT(true);
} bool assert_function_false(void)
{
TU_ASSERT(false);
} int main()
{
/* Write C code in this online editor and run it. */
printf("Hello, World! \n");
TU_ASSERT(1);
printf("-------------------------\n");
printf("%d\n", assert_function_true());
printf("-------------------------\n");
printf("%d\n", assert_function_false());
printf("-------------------------\n");
TU_ASSERT(0); return 0;
}

执行结果:

【C/C++】宏参数多对一和宏部分替换的更多相关文章

  1. C/C++语言中#的神奇作用:把宏参数字符串化/贴合宏参数

    宏中"#"和"##"的用法 一.一般用法   我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起. #define STR(s)      #s # ...

  2. 宏参数(Arguments)的扩展

    宏分为两种,一种是 object-like 宏,比如: #define STR "Hello, World!" 另一种是 function-like 宏,比如: #define M ...

  3. C语言不支持默认参数,不过可以用宏来模拟

    C语言不支持默认参数,不过可以用宏来模拟: //--------------------------------------------------------------------------- ...

  4. C/C++中 # 的神奇作用:把宏参数字符串化/贴合宏参数

    一.一般用法   我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起. #define STR(s) #s #define CONS(a,b) int(a##e##b) printf(ST ...

  5. Confluence 6.15 博客页面(Blog Posts)宏参数

    参数是让你可以用来控制宏的格式和输出的选项.在 Confluence 存储格式或者 Wiki 标记(wikimarkup)中使用的参数名与在宏浏览器中使用的标签名是不同的,在下面我们将会用括号列出  ...

  6. C语言之带有数量可变的宏参数#define

    1.定义格式如下 #define PR(...)  printf(__VA_ARGS__) ...表示可变参数,__VA_ARGS__的作用是替换省略号的内容. 2.示例 #define ERROR( ...

  7. C语言:宏参数的字符串化和宏参数的连接

    在宏定义中,有时还会用到#和##两个符号,它们能够对宏参数进行操作. # 的用法 #用来将宏参数转换为字符串,也就是在宏参数的开头和末尾添加引号.例如有如下宏定义: #define STR(s) #s ...

  8. macro-name replacement-text 宏 调试开关可以使用一个宏来实现

    C++ 预处理器_w3cschool https://www.w3cschool.cn/cpp/cpp-preprocessor.html C++ 预处理器 预处理器是一些指令,指示编译器在实际编译之 ...

  9. 宏定义(无参宏定义和带参宏定义),C语言宏定义详解

    1.宏定义说明 宏定义是比较常用的预处理指令,即使用"标识符"来表示"替换列表"中的内容.标识符称为宏名,在预处理过程中,预处理器会把源程序中所有宏名,替换成宏 ...

  10. macro-name replacement-text 宏 调试开关可以使用一个宏来实现 do { } while(0)

    C++ 预处理器_w3cschool https://www.w3cschool.cn/cpp/cpp-preprocessor.html C++ 预处理器 预处理器是一些指令,指示编译器在实际编译之 ...

随机推荐

  1. 数字孪生和GIS融合会为各自带来什么样的改变?

    数字孪生和地理信息系统(GIS)是两个强大的技术,它们在各自领域发挥着重要作用.而当数字孪生与GIS融合时,将会为它们带来更加深远的改变和增益. 数字孪生技术以数字化的方式模拟和复制现实世界中的物理对 ...

  2. loader编写小记

    此项目在一些大佬的基础上进行了修改,或许能提供一些思路.还在学习中很菜很菜,不足之处还请师傅们多多指点 tips 对shellcode使用AES + Base85加密后以txt保存在远端供下载. 针对 ...

  3. 红日靶场2-wp

    红日靶场2 环境搭建 靶场配置 靶场拓扑图如下: 首先先新建一个网卡, PC PC端虚拟机相当于网关服务器,所以需要两张网卡,一个用来向外网提供web服务,一个是通向内网. 由于作者默认的网段设置为1 ...

  4. Python——第三章:函数的定义

    函数的定义: 对某一个特定的功能或者代码块进行封装. 在需要使用该功能的时候直接调用即可 格式: def 函数的名字(): 被封装的功能或者代码块->函数体 调用: 函数的名字() 使用函数的好 ...

  5. MYSQL事务篇(高级篇)

    1.事务介绍: 一般是指要做的或所做的事情. 在计算机 术语 中是指访问并可能更新数据库中各种 数据项 的一个程序 执行单元 (unit) 2.数据库事务具有ACID四大特性. ACID是以下4个词的 ...

  6. Visual Studio 2022 Preview设置简体中文

    前言: 作为尝鲜小分队队长,对于vs的升级版Visual Studio 2022 Preview肯定也开始用上了,不过之前一直以为还没有出中文的语言包所以一直用的是英文版的,搞得英文本来不好的我很是不 ...

  7. STM32+华为云IOT制作酒驾监控系统:上车就监控

    摘要:设计一种安装在驾驶室内,能根据具体功能进行鉴别酒精浓度的系统,一起监督行车安全. 本文分享自华为云社区<基于STM32+华为云IOT设计的酒驾监控系统[玩转华为云]>,作者: DS小 ...

  8. PPT 动画-文字渐入

    插入文字,居中对齐 选中文字,将不透明度调成100%,让文字消失不见

  9. .Net Core NLog 配置

    using NLog; private static Logger logger = LogManager.GetCurrentClassLogger(); //初始化日志类 NLog.config ...

  10. compilation.templatesPlugin is not a function

    ERROR Failed to compile with 1 error TypeError: compilation.templatesPlugin is not a function - SetV ...