大约一个小时以来,我一直试图解释一些非常令人不安的行为,不确定它是由 Visual Studio 的编译器还是它的调试器引起的。我现在知道部分答案了。本质上,我在 MSVC2005 调试版本中编译并运行了以下内容:
DWORD timeStamp;
struct SomeEventStruct {
DWORD timeStamp;
// ... plus other data
};
void Magic( const SomeEventStruct & anEvent )
{
if ( anEvent.timeStamp < timeStamp )
{
ASSERT( false ); // shouldn't happen! Time does not run backwards!
}
timeStamp = anEvent.timeStamp;
}
ASSERT( false )
甚至可以执行的唯一方法是if
表达式的计算结果为真,对吗?那么,当ASSERT()
火灾发生时,我闯入调试器检查变量的值,我经常发现它timeStamp
是 0,这是怎么回事?根据定义,这是不可能的——无符号值永远不能小于零。
诚然,这是一个多线程应用程序,但没有其他线程涉及这些变量 - 它都在主 UI 线程中。我也简化了情况——它们实际上是成员变量和函数,我认为这并不重要。我认为相关的是变量值在第一次被ASSERT()
解雇并邀请我闯入调试器时是合理的,在那里我发现了一个错误的时间戳。直到继续之后,事情才开始变得奇怪。
if
最终,我发现语句和语句之间的 timeStamp 值被重置为零ASSERT( false )
。我知道唯一可能执行此操作的代码行最终连接到计时器事件(与上面的时间戳事件不同 - 计时器触发以刷新我感兴趣的系统事件的显示)。
所以现在我想知道:Windows 计时器事件是否像中断一样,在某个时刻暂停线程执行,然后在稍后返回它......或者这里发生的其他事情是 VS 调试器特有的,还是的内部运作ASSERT()
?如果我想阻止我的计时器事件处理程序运行直到上一次调用完成,是否由我来阻止重新进入?