当前位置: 首页 > news >正文

C++宏展开规则

这里主要记录一下宏嵌套宏的这中情况,例如下面这段代码:

#include <stdio.h>#define  cat(a,b)   a##b#define  xcat(x,y) cat(x, y)int main()
{int ret = xcat(xcat(1, 2), 3);printf("%d\n", ret);return 0;
}

宏嵌套宏,说的直白一点就是,一个宏函数它的参数也是宏。对于这种情况,编译器会按照下面的步骤去执行:

  • 先将实参进行替换,也就是宏展开,这里的实参是一个宏。拿上面的例子来说就是,先将最外层 xcat 宏函数的两个实参 xcat(1, 2)3 替换 xcat 的形参 xy,得到 cat(xcat(1, 2), 3)

  • 检查第一步替换的实参,如果实参也是宏,检查该宏参数是否可以被展开,宏参数是否可以被展开的判断依据是,在第一步展开得到的宏体中,该宏参数的前面或者后面没有 ###。拿上面的例子来说就是,第一步中的实参是 xcat(1, 2),第一步展开的宏体就是 cat(xcat(1, 2), 3),在这个宏体中,实参前面和后面都没有 ###,说明该宏实参可以继续展开。所以在第一步执行完得到 cat(xcat(1, 2), 3) 后,接下来是展开 xcat(1, 2),而不是展开最外层的 cat。所以这一步执行完得到 cat(cat(1, 2), 3)

  • 接下来是继续展开内层的 cat 而不是外层的 cat,这里有一点向函数的嵌套调用,一条道走到黑。因为第二步在将宏参数 xcat(1, 2) 展开后得到的还是一个宏函数调用 cat(1, 2),那么就会一直往下展开,直到最终无法展开为止,所以这里展开内层 cat 后得到的是 cat(1##2, 3) 也就是 cat(12, 3),也就是 12##3,也就是 123

再看下面这个例子:

#define foo  a,b
#define bar(x) lose(x)
#define lose(x) (1 + (x))bar(foo);
  • 展开 bar ,用实参 foo 替换形参 x,得到 lose(foo)

  • 检测实参宏是否可以被继续展开,这里是可以的,于是展开 foo,得到 lose(a, b)

  • 到这里,ab 都不是宏,无法再继续往下展开,所以就返回去展开 lose,但是 lose 宏只接收一个参数,而当前有两个参数,所以这里编译的时候会报错。这里正确的改发有下面两种:

#define foo  (a,b)
或者
#define bar(x) lose((x))
http://www.dtcms.com/a/333282.html

相关文章:

  • 【数据可视化-90】2023 年城镇居民人均收入可视化分析:Python + pyecharts打造炫酷暗黑主题大屏
  • PyTorch 训练神经网络模型,并集成到springboot项目中
  • JavaScript 原型机制详解:从概念到实战(附个人学习方法)
  • 科普:Pygame 中,`pg.Surface` v.s. `screen`
  • 使用Docker容器化Python测试Pytest项目并配置GitHub Actions CI/CD流程
  • IgH初始化--未接从站
  • 一站式学会——进制转换与位运算符详解(通俗易懂)
  • ElasticSearch不同环境同步索引数据
  • 20250815在荣品RD-RK3588-MID开发板的Android13下调通TP芯片FT8206
  • linux安装docker-compose
  • STM32在使用DMA发送和接收时的模式区别
  • 使用C# 高效实现 Word 文档内容查找与替换的6种方法
  • Java 调用 Python 脚本:实现 HelloWorld
  • 数据驱动测试提升自动化效率
  • 车辆减振器异响测试系统
  • [Pyro] 基础构件 | 随机性sample | 可学习参数param | 批量处理plate
  • find命令解读
  • 重塑工业设备制造格局:明远智睿 T113-i 的破局之道
  • 2025北京世界机器人大会:技术、场景、生态实现三重跃迁
  • ARM+OpenPLC 组合详解及经典示例
  • MySQL → SQL → DDL → 表操作 → 数据类型 知识链整理成一份系统的内容
  • 基于 ArcFace/ArcMargin 损失函数的深度特征学习高性能人脸识别解决方案
  • pandas中df.to _dict(orient=‘records‘)方法的作用和场景说明
  • 题解:CF2127D Root was Built by Love, Broken by Destiny
  • CUDA × JetPack 初学者全指南
  • Python工具箱系列(六十四)
  • go语言运算符·关系运算符
  • sql CURRENT_TIMESTAMP
  • 【DSP28335 事件驱动】唤醒沉睡的 CPU:外部中断 (XINT) 实战
  • java注释功能