0

0

C++ 宏定义由谁处理 C++预处理器工作流程科普【编译原理】

尼克

尼克

发布时间:2026-01-24 15:11:57

|

830人浏览过

|

来源于php中文网

原创

宏定义由预处理器处理,发生在词法分析之后、语法分析之前,是编译流程中最早且独立的一环;它仅进行纯文本替换,不感知类型与作用域,展开后即从编译器视野中彻底消失。

c++ 宏定义由谁处理 c++预处理器工作流程科普【编译原理】

宏定义由 C++ 预处理器(cpp)处理,不是编译器前端(如 clang -cc1 或 gcc 的 parser)负责的。 它发生在词法分析之后、语法分析之前,属于编译流程中独立且最早的一环。

预处理器在编译流程中的确切位置

标准 C++ 编译流程分四步:预处理 → 词法分析 → 语法分析 → 语义分析与代码生成。但实际顺序是:

  • 源文件先被 cpp(或集成在 clang/g++ 中的预处理模块)读入,执行所有 #define#include#ifdef 等指令
  • 输出的是一个“已展开”的纯文本流,不再含任何宏或预处理指令
  • 这个输出才交给真正的编译器(如 clang -cc1)做 tokenization 和 parsing
  • 所以 sizeof(FOO) 中的 FOO 如果是宏,在语法分析阶段早已被替换成字面量或标识符——编译器根本“看不见”原始宏名

为什么不能用宏模拟模板或类型推导

因为宏是纯文本替换,不感知类型、作用域、表达式结构:

  • #define SQUARE(x) x * xSQUARE(a + b) 中展开为 a + b * a + b,优先级错误
  • decltype(FOO) 中若 FOO 是宏,decltype 实际作用的是宏展开后的表达式,不是宏本身
  • 宏无法重载、无法参与 SFINAE、不能捕获局部作用域变量(比如 __LINE__ 是常量,不是变量)
  • 调试器看不到宏——它们在进入编译器前就消失了;GDB 中 print FOO 会报 No symbol "FOO"

如何验证宏是否已被预处理器处理

用编译器自带的预处理选项直接查看中间结果:

SpeechEasy
SpeechEasy

SpeechEasy是一种合成语音解决方案,可以让用户从文本生成高质量、易于理解的音频。

下载

立即学习C++免费学习笔记(深入)”;

  • GCC/Clang:g++ -E main.cppclang++ -E main.cpp,输出就是预处理后的代码
  • MSVC:cl /EP main.cpp(注意大小写),/P 还会生成 main.i 文件
  • 关键观察点:所有 #include 变成大段头文件内容;#define 消失;printf("val=%d", VAL);VAL 是宏,此处已变成具体数字或字符串字面量
  • 如果看到 #line 42 "main.cpp" 行,说明预处理器还在维护源码映射,方便报错定位——但这和宏无关,是预处理器的调试支持机制

宏的边界很清晰:它只活在预处理这一步里。一旦过了 -E 阶段,它就彻底不存在了。很多人试图在模板特化或 constexpr 上“绕过类型系统用宏”,本质上是在和一个早已下班的工具较劲。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

185

2023.09.27

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1492

2023.10.24

typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

108

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

336

2023.10.11

printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

73

2023.06.20

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

282

2023.11.28

mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

182

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

284

2024.02.23

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

25

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 9.3万人学习

CSS3 教程
CSS3 教程

共18课时 | 4.8万人学习

Vue 教程
Vue 教程

共42课时 | 7.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号