使用 pragma message 查找多变的 DEBUG 宏

简介: 使用 pragma message 查找多变的 DEBUG 宏

前言

这是 N 年前遇到的一个问题了。最近跟 DEBUG 宏对着干上了,正好翻到这篇总结 —— 记录了使用 pragma message 排查 同一个工程不同 CPPDEBUG 宏的值不同的过程。现对之前的总结做了更新整理,分享给各位小伙伴儿。

pragma message

使用 #pragma message 可以在编译的过程输出我们指定的信息,是排查编译问题的好帮手。以下例子摘自微软官方文档,感兴趣小伙伴儿可以直接添加到自己的工程中使用。

// pragma_directives_message1.cpp
// compile with: /LD
#if _M_IX86 >= 500
#pragma message("_M_IX86 >= 500")
#endif

#pragma message( "Compiling " __FILE__ )
#pragma message( "Last modified on " __TIMESTAMP__ )

// with line number
#define STRING2(x) #x
#define STRING(x) STRING2(x)

#pragma message (__FILE__ "[" STRING(__LINE__) "]: test")
AI 代码解读

下图是微软官方介绍 #pragma message 的文档截图,方便各位小伙伴儿阅读。

pragma-message-msdn.png

现象

test1.cppDEBUG 宏是定义了的,在 test2.cppDEBUG 宏并没有被定义。你有可能会好奇我是怎么知道的?我分别在 test1.cpptest2.cpp 里加了如下代码:

#ifdef DEBUG
#pragma message ("--------> DEBUG defined in file : " __FILE__)
#else
#pragma message ("--------> DEBUG NOT defined in file : " __FILE__)
#endif
AI 代码解读

test1.cpptest2.cpp 中,智能提示如下图:

intellisense-tip-debug-macro.png

编译输出如下图:

build-output-compare.png

从智能提示和编译输出信息都可以明显的看出,在 test1.cppDEBUG 宏是定义了的,在 test2.cppDEBUG 宏并没有被定义。好奇怪的现象。

查看工程配置

难道 DEBUG 宏不是根据工程配置来的吗?为此,特地查看了工程预定义宏。

project-defined-macros.png

从上图可知,只定义了 _DEBUG,并没有定义 DEBUG。之前一直以为定义了 _DEBUG 就同时定义了 DEBUG

看来 DEBUG_DEBUG 不一样!虽然知道了在工程中没有定义 DEBUG 宏,但是为什么在两个 cpp 里的表现不一样呢?

继续调查

继续使用伟大的 #pragma message 来排查,最后发现 test.cpp 包含了 tinyxml 库中的头文件 tinyxml.h,在此头文件中有如下语句。

tinyxml-define-debug-macro.png

至此,真相大白!!!

实战

如果你也想动手实战,可以使用下面的示例工程。

百度云 链接: https://pan.baidu.com/s/1_7RKFf-jrSdjdBZihnPl1Q 提取码: eu8f

CSDN 链接:https://download.csdn.net/download/xiaoyanilw/12502953

总结

DEBUG_DEBUG 是两个不同的宏。“官方” 支持的是 _DEBUG 而不是 DEBUG。尽量使用 _DEBUG 而不是 DEBUG

参考资料

https://docs.microsoft.com/en-us/cpp/preprocessor/message?view=vs-2019

目录
打赏
0
0
0
0
0
分享
相关文章
物联网卡应用中一些常见限制
物联网卡(IoT SIM卡)在实际应用中,除了APN配置的多样性外,还受到多种限制和约束。这些限制通常与网络运营商的政策、服务条款、技术实现以及安全需求紧密相关。以下是一些常见的物联网卡限制:
【Jlink】JLink Commander调试方法
上面的信息连可以看到当前运行的PC指针,再可以结合生成的map文件,就可以看到当前运行的函数。例如上面运行的PC指针为0x01000E72,下图是固件的map文件,查看map文件对应地址的函数为SEGGER_RTT_Write。用来读取内存的数据,参数为内存的地址和读取的长度。也可以直接用mem命令按照8位来读取。常用的命令有halt,go,mem(mem8,mem16, mem32), write(write1, write2, write4 )用来写入对应的内存地址,参数为内存的地址和写入的数据。
2572 45
【Jlink】JLink Commander调试方法
NTP网络时间同步协议详解
NTP协议是互联网上用于同步计算机时间的标准,它利用分布式时间服务器网络,通过分层管理和本地路由算法确保时间的准确性。协议涉及时间偏差、延迟和差量三个概念,用于测量与参考时钟的同步状态。基本NTP数据包包含48字节,如头部和时间戳,关键字段如跳跃指示器(LI)、版本号(VN)、模式(Mode)、层次(Stratum)等影响同步过程。协议还包括时间戳以记录不同阶段的时间点。NTP认证可选,用于数据安全。
NTP网络时间同步协议详解
Mysql给root开启远程访问权限
MySql出于安全方面考虑默认只允许本机(localhost, 127.0.0.1)来连接访问,所以需要给root账户新增一个远程访问权限。
Mysql给root开启远程访问权限
C语言中宏的一些高级用法举例
C语言中宏的一些高级用法举例
443 0
Git 最佳实践:分支管理
5月份,为统一团队git分支管理规范,刚开始准备自己写,在网上搜了下,发现不少不错的git分支管理实践。最后我为团队选择了这个git分支管理实践 A successful Git branching model ,网上有不少参考这篇文章写的中文版gitflow实践,推荐一个中文版的Git 最佳实践:分支管理。
15493 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问