gcc编译阶段打印宏定义的内容
背景
总所周知,代码量稍微大一点的C/C++项目的一些宏定义都会比较复杂,有时候会嵌套多个#if/#else判断分支和一堆#ifdef/#undef让你单看代码的话很难判断出宏定义的具体内容。
如果有一种机制能够帮助我们在构建期间打印出宏的实际内容,就能帮我们更快地捋清楚代码逻辑。
message pragma
如message pragma定义所说,可以使用它来打印一个字面意义的字符串:
#pragma message("消息文本")
而我们知道宏定义里可以使用#将宏定义字符串化;借用这种机制我们可以将使用如下宏定义来便捷地在编译期间打印宏定义:
#define PRINT_MACRO_HELPER(x) #x
#define PRINT_MACRO(x) #x"="PRINT_MACRO_HELPER(x)
#pragma message(PRINT_MACRO(YOUR_MACRO))
如果YOUR_MACRO是有被定义的,则打印:
note: #pragma message: YOUR_MACRO=xxx
若YOUR_MACRO未定义,则打印:
note: #pragma message: YOUR_MACRO=YOUR_MACRO
举个栗子:
编译test_macro_msg.cpp:
#include <iostream>
#define PRINT_MACRO_HELPER(x) #x
#define PRINT_MACRO(x) #x "=" PRINT_MACRO_HELPER(x)
#define NUMBER_MACRO 3.14159
#define STRING_MACRO "This is a string."
#pragma message(PRINT_MACRO(NUMBER_MACRO))
#pragma message(PRINT_MACRO(STRING_MACRO))
#pragma message(PRINT_MACRO(UNDEF_MACRO))
int main(int argc, char** argv)
{
return 0;
}
编译过程中输出:
> g++ cstr2string.cpp -o cstr2string
cstr2string.cpp:9:42: note: #pragma message: NUMBER_MACRO=3.14159
#pragma message(PRINT_MACRO(NUMBER_MACRO))
^
cstr2string.cpp:10:42: note: #pragma message: STRING_MACRO="This is a string."
#pragma message(PRINT_MACRO(STRING_MACRO))
^
cstr2string.cpp:11:41: note: #pragma message: UNDEF_MACRO=UNDEF_MACRO
#pragma message(PRINT_MACRO(UNDEF_MACRO))
^
gcc编译阶段打印宏定义的内容的更多相关文章
- c++编译时打印宏定义
#pragma message("this is message") #pragma message只能打印字符串,如果想打印任何宏定义可使用: #define PRINT_MAC ...
- 查看GCC的内置宏定义
开发过程中我们常常需要使用宏定义.. 为了尽可能多的使用GCC为我们提供的特性,首先我们需要知道gcc提供了那些特性... gcc -dM -E - < /dev/null 没错,就这么一句话就 ...
- 获取gcc和clang的内置宏定义
下面是对Gcc的内置宏定义的解释: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html https://github.co ...
- gcc编译c语言程序
编译:当前源代码编译成二进制目标文件(.obj文件) 链接(link):将生成的.obj文件与库文件.lib等文件链接,生成可执行文件(.exe文件). 一个现代编译器的主要工作流程如下: 源程序 ...
- gcc 编译 + 选项【转】
转自:http://blog.csdn.net/princess9/article/details/6567678 一般来说要现有项目中的编译选项,设置新的project的编译选项 编译器 就是将“高 ...
- gcc 编译 c++ 程序(转载)
单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码: /* helloworld.cpp */ #include <iostream& ...
- VC中预处理指令与宏定义详解
刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个 ...
- GCC编译过程与动态链接库和静态链接库
1. 库的介绍 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可 ...
- Makefile中进行宏定义-***
实际上是gcc命令支持-D宏定义,相当于C中的全局#define: gcc -D name gcc -D name=definition Makefile中可以定义变量(和宏很像),但是是给make解 ...
随机推荐
- jQuery 第二章 实例方法 DOM操作取赋值相关方法
取赋值相关方法: .html() .text() .val() .size() .addClass() .removeClass() .hasClass() .html() html方法干嘛的呢,底 ...
- 设置searchDisplayController的searchResultsTableView的UITableViewStyle为grouped
[self.searchDisplayController setValue:[NSNumber numberWithInt:UITableViewStyleGrouped] forKey:@&quo ...
- exgcd 学习笔记
最大公约数 更相减损术:\(\gcd(x,y)=\gcd(x,y-x)(x\leq y)\). 证明: 设 \(\gcd(x,y)=k\),则 \(x=kp,y=kq,\gcd(p,q)=1\). 那 ...
- Hibernate的配置跟简单创建一个表并插入一条数据
首先官网下载一个hibernate的架包,由于时间关系,博主已经分享到了百度网盘:https://pan.baidu.com/s/1Mw0Og3EKnouf84Njz9UicQ,提取码lens Hib ...
- linux ssh远程连接控制 linux(centOS) 口令、密钥连接
sshd服务提供两种安全验证的方法: 基于口令的安全验证:经过验证帐号与密码即可登陆到远程主机. 基于密钥的安全验证:需要在本地生成"密钥对"后将公钥传送至服务端,进行公共密钥的比 ...
- Qt实现客户端与服务器消息发送与文件传输
Qt实现客户端与服务器消息发送与文件传输需要使用到 QTcpSocket:提供套接字QTcpServer:提供基于TCP的服务端,官方文档的解释如下: This class makes it poss ...
- Python机器学习笔记:异常点检测算法——LOF(Local Outiler Factor)
完整代码及其数据,请移步小编的GitHub 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/MachineLearningNote 在数据挖掘方面,经常需 ...
- 探究 | 如何捕获一个Activity页面上所有的点击行为
前言 最近逛wanAndroid论坛,发现一个有趣的问题:如何捕获一个Activity页面上所有的点击行为. 一起研究下吧,不想看源码的小伙伴可以直接看文末总结- 准备工作 先得罗列出页面上的一些点击 ...
- Spring Boot 使用 XXL-JOB
一.配置部署调度中心 1.1 下载源码 https://github.com/xuxueli/xxl-job 1.2 数据库初始化 执行 /xxl-job/doc/db/tables_xxl_job. ...
- 第三十九章、PyQt显示部件:OpenGL Widget部件功能简介及使用其显示图片
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 OpenGL Widget部件是一个Op ...