如何在VS中有效地调试宏?

时间:2009-09-07 15:17:57

标签: c++ debugging visual-studio-2008 macros

我的(非托管)C ++代码中有一个非常复杂的宏。有没有办法在VS调试器中扩展宏?或者可能还有另一种调试宏的方法吗?

F.e。我想在其中放置一个断点。

(是的,我知道宏很糟糕。)

10 个答案:

答案 0 :(得分:18)

右键单击并转到“属性”,转到项目或源文件属性。在配置属性 - > C / C ++ - >预处理器下,将“生成预处理文件”设置为带或不带行号,无论您喜欢哪个。这将显示您的宏在上下文中展开的内容。如果你需要在实时编译的代码上进行调试,只需剪切并粘贴它,并在调试时将其放在宏的位置。

答案 1 :(得分:4)

编译器很好地扩展了宏。 获取扩展宏的编译列表。

将展开的宏插入代码中。 重新编译,你应该能够通过它, 做一个简单的测试。

一般来说,当我构建一个复杂的宏时, 我先硬编码,然后测试一下。 然后我把它变成一个宏。

对于2008年,this可能会有所帮助

答案 2 :(得分:3)

我从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

当我打开output.cxx文件时,应该有一些空行,底部是扩展的宏,如:

public: void GetMyVariable(){ return m_MyVariable; };

您可以在不编译的情况下测试宏,这样可以快速进行。

答案 3 :(得分:3)

我听到了关于这个主题的所有可能的否定答案:

  • 宏只能展开而不能评估
  • 预处理器应该解析包含文件
  • 嵌套宏可能过于复杂
  • 条件预处理可能很棘手
  • 宏是邪恶的,只是避免它们
  • 等等....

他们都是真的,但IMO却与日常编程的现实相冲突。

事实上,在旧的C项目上工作,其中宏主要用作函数,这对我来说至关重要。使用/ P生成所有预处理文件有效,但过度使用和耗时。我只需要一个工具来扩展一个简单的宏,在其他文件中定义几行或最多。

怎么做?

  1. 在Linux上只需使用GDB及其扩展宏功能
  2. 在Windows上我使用https://www.jetbrains.com/resharper-cpp/集成 进入Visual Studio
  3. 所以,是的,从实际意义上讲,它是可能的。

答案 4 :(得分:2)

如果要查看预处理器生成的扩展代码,则可以使用gcc使用-E标志获取它。命令如下:

$ gcc -E <source code> -o <preprocessed file name>

您可以使用带有扩展代码的宏替换原始源代码,并放置您想要放置的断点。

答案 5 :(得分:1)

如果您正在使用Visual Studio处理使用宏的C或C ++项目,请获取Resharper for C++(我相信有试用版)。它允许您单击宏并完全展开或分阶段展开。我们有一些非常复杂的嵌套宏,它是理解它们的唯一方法。

答案 6 :(得分:0)

用邪恶的方法来对抗邪恶。手动扩展宏的一个实例,直到完成调试,或者cpp实用程序可以帮助您扩展所有宏,但我不确定它是否有Windows版本。

答案 7 :(得分:0)

  

我说过这些宏非常复杂吗?我想只扩展一层或两层,而不是所有的宏(否则它显然是不可读的)......在调试时

如果没有太多的 想要扩展的宏,那么您可以在要调试的代码段之前简单地#undef它们。然后使用上面提到的[Generate Preprocessed File]进行编译。编译将失败,但您将在预处理输出中获得可用的剪切并进行正确的扩展。复制粘贴,删除#undef-s并调试。

可悲的是,处理C风格宏的最好的朋友是内联模板以及优秀的优化编译器。

答案 8 :(得分:0)

使用内联函数(强制内联,如果你真的是这个意思)并坚持下去!这将更有效(如果你优化了perf,它只会带来性能)并且可维护。你使用宏松散了很多:类型检查&amp;安全

编译器不存在宏,它们仅用于预处理器。这个可以在不寻找副作用的情况下进行文本替换。所以宏实际上从未被调用过,你无法调试它们。无论您如何编写宏,都可以使用误用。就像在这个例子中一样:

#define SQUARE(a) ((a)*(a))

注意(`)'以防止像SQUARE(3 + 2)这样的替换。但是他们没有防范:

int a = 1;
int b = SQUARE(++a);

人们会期望它是4但你最终得到的6并不是真正的正方形。随着它扩展到int b = (++a)*(++a);你不会遇到内联函数的问题。

请注意,内联函数的实现必须在您使用它的位置对编译器可见。对于新手用户来说,调试也会很奇怪:因为有很多内联函数的实例,如果你想将执行点移动到另一个地方,你会得到一个庞大的方法列表。

答案 9 :(得分:0)

是的,你可以。

找到Debug文件夹中预处理器生成的预处理文件

因此,如果您的宏是用 testing.c 文件编写的,那么预处理的文件将被称为 testing.i

在那里你可以看到宏是如何扩展的。

要调试它,只需将此代码复制粘贴到您的代码:)