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解 ...
随机推荐
- 「CSP-S 2019」划分
description loj 3212 solution 首先容易想到\(n^3\)DP,即令\(f_{i,j}\)表示前\(i\)个数的划分,其中最后一段是从\(j\)开始时的答案 于是有 \[f ...
- jQuery 根据value设置radio默认选中
jQuery 根据value设置radio默认选中:HTML: <input type="radio" name="type" value="1 ...
- python批量生成SQL语句
1,首先写一条能运行成功插入SQL的语句 INSERT INTO sign_guest(realname,phone,email,sign,event_id)VALUES("jack&quo ...
- Linux中influx数据库进程杀不掉,父进程为1
influx数据库一直杀不掉,父进程为1是个僵尸进程 后来我才发现,influx是运行运行状态 我只需要使用命令,停掉influx即可停止改进程
- CodeBlocks相关配置
因为我平时CodeBlocks的使用频率不高,但考试时需要用到,担心忘记相关配置在哪里调整,在此记录下. 打开调试模式 首先一定是创建项目. 项目创建完成后,配置调试器\(GDB\)路径 打开调试窗口 ...
- 多态,向上转型,向下转型,final关键字
多态 概述 多态封装性,继承性之后,面向对象的第三大特性. 定义 多态:是指同一种行为,具有多个不同的表现形式. 生活中,比如跑的动作,猫,狗,大象跑起来的动作都是不一样的,再比如飞的动作 ...
- zk下的kafka节点
zk从某种程度上说是kafka的单点失效组件. /brokers:里面保存了Kafk集群的所有信息,包括每台broker的注册信息,集群上所有topic的信息等. /controller:保存了Kaf ...
- PHP AES加密封装类
简介 PHP AES 加密解密常用封装类 使用方式 $key = 123; $aes = new Aes($key); $data = ['a' => 1]; $aes->decrypt( ...
- C语言中connst用法
1.const一般用来定义只读变量,这个变量的之只能在初始化时赋值,如果初始化时没有赋值,则默认为0.如果在其他地方试图更改此值,编译会报错.如: 1 #include<stdio.h> ...
- web 应用、 框架 及HTTP协议
web 应用 一.web 应用程序是什么 Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件 应用程序有两种模式C/ ...