我的(非托管)C++代码中有一个非常复杂的宏。有没有办法在VS调试器中扩展宏?或者有没有其他方法来调试宏?例如,我想在其中放置一个断点。(Yes,我知道宏是不好的。)
ukqbszuj1#
通过右键单击并转到属性,转到项目或源文件属性。在配置属性-〉C/C++-〉预处理器下,将生成预处理文件设置为带行号或不带行号,根据您的喜好而定。这将显示您的宏在上下文中扩展到什么。如果您需要在实时编译的代码上调试它,只需剪切并粘贴它,并在调试时将其放在您的宏的位置。
unftdfkk2#
我听到了关于这个主题的所有可能的否定答案:
他们都是真的,但海事组织,他们与现实的日常编程碰撞。事实上,在旧的C项目中,宏大多数只是作为函数使用,这对我来说至关重要。用/P生成所有预处理文件是可行的,但过于繁琐和耗时。我只是需要一个工具来扩展一个简单的宏,该宏定义在其他文件中的几行以上或最多几行。如何做到这一点?1.在Linux上,只需使用GDB及其扩展宏功能1.在Windows上,我使用集成到Visual Studio中的https://www.jetbrains.com/resharper-cpp/所以,是的,在实际意义上,这是可能的。
uwopmtnx3#
编译器很好地扩展了宏。得到一个宏扩展后的编译列表。将扩展的宏插入到你的代码中。重新编译,你应该能够逐步通过它,做一个简单的测试。一般来说,当我构建一个复杂的宏时,我会先硬编码,然后测试,再把它变成一个宏。对于2008年,this可能会有所帮助
8ulbf1ek4#
我从http://www.codeproject.com/Tips/320721/Macro-expansion-in-VCplusplus学到了调试宏的最佳方法。我所做的是创建一个名为“test.cxx”的cxx文件,在里面我只放了宏和test.cxx的一些使用示例:
#define GetMacro(param1) \ public: void Get##param1(){ return m_##param1; } GetMacro(MyVariable);
在命令行中输入:
c:\ cl /EP test.cxx > output.cxx
当我打开输出.cxx文件应该有一些空行,并在底部展开宏,如:
public: void GetMyVariable(){ return m_MyVariable; };
你可以不用编译就测试宏,这样做很快。
f0brbegy5#
如果你想看到预处理器生成的扩展代码,那么你可以使用gcc的-E标志来获取它。
$ gcc -E <source code> -o <preprocessed file name>
您可以使用macro将原始源代码替换为扩展代码,并放置您想要放置的任何断点。
4zcjmb1e6#
如果你正在使用Visual Studio来处理使用宏的C或C++项目,那么就使用Resharper for C++(我相信有一个试用版)。它允许你点击一个宏,然后完全展开它,或者分阶段展开它。我们有一些极其复杂的嵌套宏,这是理解它们的唯一方法。
wztqucjr7#
我说过宏非常复杂吗?我想在调试时只展开一两层,而不是所有的宏(否则它显然是不可读的)...如果没有太多的宏你不想扩展,那么你可以简单地在你想调试的代码段之前#undef它们。然后如上所述用[Generate Preprocessed File]编译。编译会失败,但是你会在预处理输出中得到一个可用的代码段,并带有正确的扩展。复制粘贴,删除#undef-s并调试。遗憾的是,处理C风格宏最好的朋友是内联、模板和一个好的优化编译器。
iezvtpos8#
使用内联函数(如果你真的想内联,就强制内联)并坚持使用它!这样会更高效(如果你优化了perf,只有当它带来性能时才内联)和可维护性。使用宏会损失很多:类型检查和安全。宏并不存在于编译器中,它们只存在于预处理器中。这个宏在不寻找副作用的情况下进行文本替换。所以宏实际上从来没有被调用过,你也不能调试它们。无论你如何编写宏,误用总是可能的。就像这个例子:
#define SQUARE(a) ((a)*(a))
注意( ')可以防止像SQUARE(3+2)这样的替换,但是它们不能防止:
(
int a = 1; int b = SQUARE(++a);
有人会期望它是4,但你最终得到的是6,这不是真正的正方形,当它扩展到int b = (++a)*(++a);时,你就不会有内联函数的麻烦了。注意,内联函数的实现必须在你使用它的地方对编译器是可见的,而且调试对于新手来说也会很奇怪:因为一个内联函数有很多示例,如果你想把执行点移到另一个地方,你会得到一个巨大的方法列表。
int b = (++a)*(++a);
qjp7pelc9#
是的,你可以。在Debug文件夹中找到由预处理器生成的预处理文件。因此,如果您的宏是在 * testing. c * 文件中编写的,则预处理文件将称为 * testing. i *在那里,您可以看到宏是如何展开的。要调试它,只需将此代码复制粘贴到您的:)
9条答案
按热度按时间ukqbszuj1#
通过右键单击并转到属性,转到项目或源文件属性。在配置属性-〉C/C++-〉预处理器下,将生成预处理文件设置为带行号或不带行号,根据您的喜好而定。
这将显示您的宏在上下文中扩展到什么。如果您需要在实时编译的代码上调试它,只需剪切并粘贴它,并在调试时将其放在您的宏的位置。
unftdfkk2#
我听到了关于这个主题的所有可能的否定答案:
他们都是真的,但海事组织,他们与现实的日常编程碰撞。
事实上,在旧的C项目中,宏大多数只是作为函数使用,这对我来说至关重要。用/P生成所有预处理文件是可行的,但过于繁琐和耗时。我只是需要一个工具来扩展一个简单的宏,该宏定义在其他文件中的几行以上或最多几行。
如何做到这一点?
1.在Linux上,只需使用GDB及其扩展宏功能
1.在Windows上,我使用集成到Visual Studio中的https://www.jetbrains.com/resharper-cpp/
所以,是的,在实际意义上,这是可能的。
uwopmtnx3#
编译器很好地扩展了宏。得到一个宏扩展后的编译列表。
将扩展的宏插入到你的代码中。重新编译,你应该能够逐步通过它,做一个简单的测试。
一般来说,当我构建一个复杂的宏时,我会先硬编码,然后测试,再把它变成一个宏。
对于2008年,this可能会有所帮助
8ulbf1ek4#
我从http://www.codeproject.com/Tips/320721/Macro-expansion-in-VCplusplus学到了调试宏的最佳方法。
我所做的是创建一个名为“test.cxx”的cxx文件,在里面我只放了宏和test.cxx的一些使用示例:
在命令行中输入:
当我打开输出.cxx文件应该有一些空行,并在底部展开宏,如:
你可以不用编译就测试宏,这样做很快。
f0brbegy5#
如果你想看到预处理器生成的扩展代码,那么你可以使用gcc的-E标志来获取它。
您可以使用macro将原始源代码替换为扩展代码,并放置您想要放置的任何断点。
4zcjmb1e6#
如果你正在使用Visual Studio来处理使用宏的C或C++项目,那么就使用Resharper for C++(我相信有一个试用版)。它允许你点击一个宏,然后完全展开它,或者分阶段展开它。我们有一些极其复杂的嵌套宏,这是理解它们的唯一方法。
wztqucjr7#
我说过宏非常复杂吗?我想在调试时只展开一两层,而不是所有的宏(否则它显然是不可读的)...
如果没有太多的宏你不想扩展,那么你可以简单地在你想调试的代码段之前#undef它们。然后如上所述用[Generate Preprocessed File]编译。编译会失败,但是你会在预处理输出中得到一个可用的代码段,并带有正确的扩展。复制粘贴,删除#undef-s并调试。
遗憾的是,处理C风格宏最好的朋友是内联、模板和一个好的优化编译器。
iezvtpos8#
使用内联函数(如果你真的想内联,就强制内联)并坚持使用它!这样会更高效(如果你优化了perf,只有当它带来性能时才内联)和可维护性。使用宏会损失很多:类型检查和安全。
宏并不存在于编译器中,它们只存在于预处理器中。这个宏在不寻找副作用的情况下进行文本替换。所以宏实际上从来没有被调用过,你也不能调试它们。无论你如何编写宏,误用总是可能的。就像这个例子:
注意
(
')可以防止像SQUARE(3+2)这样的替换,但是它们不能防止:有人会期望它是4,但你最终得到的是6,这不是真正的正方形,当它扩展到
int b = (++a)*(++a);
时,你就不会有内联函数的麻烦了。注意,内联函数的实现必须在你使用它的地方对编译器是可见的,而且调试对于新手来说也会很奇怪:因为一个内联函数有很多示例,如果你想把执行点移到另一个地方,你会得到一个巨大的方法列表。
qjp7pelc9#
是的,你可以。
在Debug文件夹中找到由预处理器生成的预处理文件。
因此,如果您的宏是在 * testing. c * 文件中编写的,则预处理文件将称为 * testing. i *
在那里,您可以看到宏是如何展开的。
要调试它,只需将此代码复制粘贴到您的:)