背景

总所周知,代码量稍微大一点的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编译阶段打印宏定义的内容的更多相关文章

  1. c++编译时打印宏定义

    #pragma message("this is message") #pragma message只能打印字符串,如果想打印任何宏定义可使用: #define PRINT_MAC ...

  2. 查看GCC的内置宏定义

    开发过程中我们常常需要使用宏定义.. 为了尽可能多的使用GCC为我们提供的特性,首先我们需要知道gcc提供了那些特性... gcc -dM -E - < /dev/null 没错,就这么一句话就 ...

  3. 获取gcc和clang的内置宏定义

    下面是对Gcc的内置宏定义的解释: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html https://github.co ...

  4. gcc编译c语言程序

    编译:当前源代码编译成二进制目标文件(.obj文件) 链接(link):将生成的.obj文件与库文件.lib等文件链接,生成可执行文件(.exe文件).   一个现代编译器的主要工作流程如下: 源程序 ...

  5. gcc 编译 + 选项【转】

    转自:http://blog.csdn.net/princess9/article/details/6567678 一般来说要现有项目中的编译选项,设置新的project的编译选项 编译器 就是将“高 ...

  6. gcc 编译 c++ 程序(转载)

    单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码: /* helloworld.cpp */ #include <iostream& ...

  7. VC中预处理指令与宏定义详解

    刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个 ...

  8. GCC编译过程与动态链接库和静态链接库

    1. 库的介绍 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可 ...

  9. Makefile中进行宏定义-***

    实际上是gcc命令支持-D宏定义,相当于C中的全局#define: gcc -D name gcc -D name=definition Makefile中可以定义变量(和宏很像),但是是给make解 ...

随机推荐

  1. 接上一篇:(四) 控制反转(IOC)/ 依赖注入(DI)

    spring 核心功能:beans.core.context.expression Spring设计理念 Spring是面向Bean的编程 Spring三个核心组件(Core.Context.Bean ...

  2. python3 Redis未授权检测脚本

    `import sys import getopt import socket def get_target(): opts, args = getopt.getopt(sys.argv[1:], ' ...

  3. Java基础教程——注解

    注解 JDK 5开始,Java支持注解. 注解,Annotation,是一种代码里的特殊标记,这些标记可以在编译.类加载.运行时被读取并执行,而且不改变原有的逻辑. 注解可以用于:生成文档.编译检查. ...

  4. 【不尽如人意的redisTemplete封装】

    线下项目里对spring redisTemplete进行了简单的封装,但是项目里关于其序列化的配置真的有点一言难尽: 可以看到这里用了JdkSerializationRedisSerializer去对 ...

  5. 【mq读书笔记】定时消息

    mq不支持任意的时间京都,如果要支持,不可避免的需要在Broker层做消息排序,加上持久化方面的考量,将不可避免地带来巨大的性能消耗,所以rocketMQ只支持特定级别的延迟消息. 在Broker短通 ...

  6. MySQL必知必会:简介undo log、truncate、以及undo log如何帮你回滚事物

    目录 一.前言 二.undo log表空间 三.关于undo log默认的配置 四.如何将undo log放到单独的表空间 文章公众号首发,持续更新中 五.rollback segment 六.什么是 ...

  7. C语言项目——工程化编程的案例分析

    一.VSCode安装及环境配置 初始在Win下安装Mingw-w64/GCC 和 GDB,在VSCode下打开项目案例,发现在linktable中需要包含pthread头文件.此文件是基于Linux系 ...

  8. Spring Cloud Alibaba 初体验(一) Nacos 配置中心

    一.Nacos 下载与初始化配置 本文使用1.2.0,下载地址:https://github.com/alibaba/nacos/releases Nacos 单机模式支持持久化配置到 MySQL 数 ...

  9. Java 生成有序 UUID

    UUID.randomUUID() 生成的 UUID 是无序的,如果作为数据主键,不利于索引 Hibernate 的 UUIDHexGenerator.generate() 方法可以生成有序的 UUI ...

  10. 20190705_关于winform程序修改程序名后, 报未将对象引用设置到对象的实例

    winform做了一个小项目, 其中要用到数据库连接, 字符串, private string ConnStringSource = System.Configuration.Configuratio ...