我可以用其他方式而不是编写虚拟代码吗?
是的!
在调试器中,您应该能够添加断点并将其设置为仅在满足特定条件时才中断。如何执行此操作取决于您的 IDE,但在我的 IDE 中,我可以右键单击代码编辑器排水沟或单独的断点窗口中的断点,然后从弹出菜单中选择属性。然后我得到这个对话框:
您可以看到我设置了“条件”属性,每次代码遇到该断点时都会评估该属性 - 但断点只会在条件为true 时中断。即,如果check() 在一切正常时返回true,则!check() 将在check() 返回false 时使其中断。
如果经常调用此方法,这往往会稍微减慢您的程序,因为通常要评估这样的表达式,调试器必须(内部)中断并评估某些内容。但它的功能很简洁。请注意您还可以设置的所有其他属性,而且在单击“高级”按钮后,这甚至还没有显示对话框的样子...
回答您的其他问题:
如果我在空的 if 循环中放置断点,调试器将不会停止
在那里,它只在可以执行的指令处停止。即使你这样做
诠释一个;只是一个不会停止的声明。
如果 if 块(不是循环)是空的,那么它就没有什么可以停止的了。它只能在实际代码上停止。 int a; 只是一个变量声明;对于简单类型,实际上不会为此生成任何代码。 (不过,它可以用于更复杂的类型,例如 MyClass a;,因为它会调用构造函数。)即使您编写更多代码:
if (!check()) {
int a;
a = 5;
b = a;
}
您的编译器可能仍然不会为此生成任何代码,因为它可能会发现代码实际上从未执行任何操作。这在一定程度上取决于您的优化设置,但即使没有任何特定的优化设置,一些编译器也会对其进行优化。
有时由于各种原因(有时只是条件评估的速度),中断代码而不是使用 IDE 会很方便。在这种情况下,我倾向于使用函数调用来中断,因为编译器不知道函数不会修改程序的状态,也不能优化掉:
if (!check()) {
rand(); // <- breakpoint here
}
但通常充分利用您的 IDE 和调试器功能是一种更好的方法。
编辑: 因为这得到了赞成(谢谢大家),我想我会添加另一种方法,以保持完整性。软件/调试器断点出现interrupt 3, which is patched in by the debugger. int 3 汇编指令只有一个字节长,因此可以修补任何其他指令;当程序中断时,可以暂时将旧指令修补回去。但是除了调试器在运行时将其放入,您还可以将其放入代码中。
换句话说,您可以通过类似的方式强制您的程序中断代码(并被调试器捕获;如果您不在调试器下运行,这可能会导致问题;通常,您的程序将中止)。语法取决于您的环境:
if (!check()) {
__asm int 3
}
甚至更好的是,避免依赖环境的代码,许多 C++ 编译器都有内在函数或宏,例如 DebugBreak(); 或 __debugbreak,您可以像这样使用它们:
if (!check()) {
DebugBreak();
}
当您在调试器下运行程序时,您会发现该行的执行中断。
没有理由正常使用它。我见过一个自定义断言处理程序,它在断言失败时中断调试器,但允许之后继续执行。