为什么调试器不知道#define'd常量?
在调试我的代码时,我经常想知道#defined'd常量的值。 但调试器似乎并不知道它们的值。 这意味着我必须四处寻找包含路径等以查找#define行。 有一些技巧可以让这更简单吗?
更新:我必须授予托尼D绿色记号标题问题的详细答案,但我也upvoted使用const
而不是#define(我也测试过, enum
也可以)。 最后,使用F12来查找原始的#define行是另一个好主意。
对于Google的价值10分钟,似乎Visual Studio不支持这一点。
有些编译器确实会这样做,但有一个原因是它有点脆弱/尽力而为......
先老调重弹,并打掉这个共同但有虚假说明:有是替代了预处理宏的使用文本“正确”的编制开始前一个概念上不同的预处理步骤,但实在没有理由在预处理阶段不能通过记录#define
和#undef
ine语句向前,以包含其他调试信息。
什么是痛苦,什么是直观,通常被认为是“ #define
-ing一个预处理器常量”是不是像什么?
const Some_Type some_identifier = some_value;
...后者在应用程序的命名空间heirarchy中具有特定的位置,并且实际上不能更改,而#define
可以#undef
-ined并重新#define
d任意次数 ,以使“value “特定行代码中的预处理器宏可以取决于该行如何被包括在翻译单元中: 每个翻译单元中的相同行的每个包含可以具有用于该宏的不同值(或无值) 。
因此,在通过某些代码进行调试时显示宏的“值”是有问题的 - 只能保证在特定翻译单元的特定行中具有单个值,但程序员通常希望调试器显示和导航程序根据源文件中的行。
考虑:
use_x.h
class T ## X {
void g() { ... }
};
some_app.cc
#define X 2783
#include "use_x.h"
#undef X
#define X 2928
#include "use_x.h"
void f() {
const int last_x = X;
}
如果你的调试器通过了上面的f()
,那么X
可以被认为是2928
,但是如果你正在逐步调试g()
的版本 - 调试器将会很难理解类名和用于创建它的X
值,或者计算出其他方式显示的内容....
如果将鼠标悬停在某个宏的某个其他行上(可能从另一个翻译单元中链接),则它会变得更糟 - 调试器不可能知道您是否对该宏的最后一个值感兴趣执行已经通过,或者如果继续执行(如果它甚至可以预测可能首先发生的任何分支)或者调试器停止在该行的宏的值(如果有),那么它可能具有的下一个值。
所以,一些工具链(编译器/调试信息编码/调试器)只是不买进这个烂摊子。 更好的工具可以跟踪简单的案例,然后不显示任何内容 - 或可能的值列表 - 对于分析过于复杂的案例。 显示错误的值比没有更糟糕。
它在调试器中没有帮助,但是当需要检查宏值/替换值时,可以尝试使用cl /E
(对于GCC /为选项的-E
)以为翻译单元提供预处理输出 - 然后您可以看到什么替换由预处理器完成。
在编译之前,预处理器会对宏进行评估和解析。 编译后的程序并不知道它们的值:编译后的程序完全不包含它们的踪迹。 调试器没有什么可以检查的。
考虑宏是一个代码生成工具,一切都将变得清晰。
某些编译器确实有一个标志,您可以设置该标志来保留各种预处理器定义的值,并将其列在特定区域中,以用于调试目的。 不过,我不知道如何让VS在VS中发生。 我将使用相关开关仅运行预处理器,然后检查结果。
'#define'd常量对于调试器是未知的,因为它们在编译之前被预处理,并且它们在代码中的出现被值替换。
如果你想要一个常量值,为什么不使用const? 通过这种方式,您可以在调试器中看到该值,并强制编译器检查是否错误地尝试更改代码中的值。 #define没有任何安全性。
链接地址: http://www.djcxy.com/p/73311.html