【发布时间】:2015-08-18 17:12:44
【问题描述】:
这是一个奇怪的问题。我在一个类上有一个函数,其中有一个断点,即使函数的其余部分没有运行,它也会被命中。重现此代码所需的代码量可能无法在此处发布,但这就是我所看到的:
MyClass.h:
enum OptionsEnum { OPTION_1, OPTION_2 };
struct OptionsStruct
{
OptionsEnum options;
int value;
};
class MyClass
{
private:
Initialize(...);
Process(const OptionsStruct&);
OptionsStruct m_Options { };
}
MyClass.cpp:
#include "MyClass.h"
void MyClass::Initialize(...)
{
...do some stuff with local variables... //<--Breakpoint here not triggered
...do some more stuff...
Process(m_Options); //<--Breakpoint here is triggered! How?!
...do yet more stuff... //<--Breakpoint here not triggered
}
void MyClass::Process(const OptionsStruct& options)
{
...do some other stuff... //<--Breakpoint here not triggered
}
我看到很多帖子都有相反的问题,他们期望被命中的断点被优化出来,因此从未被触发,但我想不出相反的可能:优化导致在一个从未调用过的函数中间设置断点。
单步执行代码表明它从未真正进入Initialize() 函数,但是当使用断点运行时,它会触发它。可以肯定的是,我什至关闭了优化并让它运行,它仍然会到达那个断点。只有那个断点。我在函数的每一行代码上都放了一个断点,只有那个会命中。 Process() 中的断点也不会触发,即使它是由触发的那一行调用的。
模式似乎是只有其中包含成员变量的行才会被命中。当他们这样做时,如果您将鼠标悬停在 m_Options 上,则结构中的所有字段都是垃圾(未初始化)值。
调用堆栈没有帮助 - 它只指向[External Code] 和下面的[Frames below may be incorrect and/or missing...] 该函数是私有的,所以我不知道外部代码如何调用它。这是调试器中的错误吗?某种优化魔法?什么可能导致这样的事情发生?
【问题讨论】:
-
确保你在调试模式下编译你的项目,没有优化。我可能只是猜测您将其编译为 RELEASE 或 DEBUG,但经过优化,编译器优化了一些使调试过程变得混乱的东西。
-
C++ 编译器 (clxx.exe) 在解释
OptionsStruct m_Options { };行时崩溃。如果我删除大括号,一切正常,没有断点被击中。很奇怪。 -
@AlexLop。我们实际上做了相反的事情——它被编译为 RELEASE 但没有优化。代码的其他部分取决于它是否处于发布版本中。我可以尝试回到 DEBUG,但每次切换模式时大约需要 20 分钟的编译时间(代码库非常庞大),所以我不经常这样做。
-
@AustinMullins - 你使用的是 C++11 吗?这在 C++0x 中不可用。它基本上只是用每个字段的默认值初始化结构。此外,我不希望其他人仅使用此代码就能看到相同的行为。我们的实际代码库非常大,不可能以任何有意义的方式在这里发布。
-
是的,它是 C++11。我可以整天在
_tmain中做初始化列表和 lambda,当我试图在类定义中使用空的初始化列表时,我感到很困惑。
标签: c++ debugging c++11 visual-studio-2013 breakpoints