不可能的事件顺序
Impossible sequence of events
我试图在for
循环中跟踪一个神秘的迭代器问题。我在迭代器的operator!=
中得到一个错误,这通常意味着正在比较的迭代器不属于同一个容器。跟踪到微软库的实现,operator!=
调用operator==
,其中测试为真:
bool operator==(const _Myiter& _Right) const
{ // test for iterator equality
#if _ITERATOR_DEBUG_LEVEL == 2
if (this->_Getcont() == 0
|| this->_Getcont() != _Right._Getcont())
{ // report error
_DEBUG_ERROR("list iterators incompatible");
为了获得更多的信息,我写了这个小函数来替换for
循环中的!=
:
template<typename iter>
bool bang_equal(const iter & left, const iter & right)
{
static int count = 0;
auto p1 = left._Getcont();
auto p2 = right._Getcont();
ATLTRACE("Iterator comparison left _Getcont()=%p right _Getcont()=%p %dn", p1, p2, ++count);
MemoryBarrier();
bool b = left != right;
MemoryBarrier();
auto p3 = left._Getcont();
auto p4 = right._Getcont();
ATLTRACE(" left _Getcont()=%p right _Getcont()=%p %dn", p3, p4, ++count);
return b;
}
这就是有趣的地方。我仍然得到表达式left != right
中的错误,调试器停止在那里,但要么第一个ATLTRACE
已被跳过,要么第二个已提前运行!调试器的输出有两行,并且调试器显示的count
的值与输出的最后一行匹配。
Iterator comparison left _Getcont()=07D0B2C8 right _Getcont()=07D0B2C8 2984
left _Getcont()=07D0B2C8 right _Getcont()=07D0B2C8 2985
Myprog.exe has triggered a breakpoint.
查看反汇编窗口,可以看到按照预期顺序的指令。我难住了。可能会发生什么?
终于想通了。Microsoft函数_Debug_message
显示一个对话框,询问您是要中止、重试(调试)还是忽略错误。在显示对话框时,消息泵仍在运行,从而允许进行其他活动。我的函数再次被调用,这一次它运行到完成,在这个过程中生成了大量的调试输出。如果我在库代码的_DEBUG_ERROR
行上设置一个显式断点,我就可以捕获错误,而无需在后台执行额外的执行。事后回顾调试输出,我可以看到预期的错误输出确实在那里,只是隐藏得太深了,我从来没有看到过它。
我的直觉告诉我,Occam剃刀是这里最可能的解释:特别是在迭代期间使迭代器无效。在for循环中没有++iter
这一事实进一步强调了它不是对每个元素进行直接迭代。
它可能不是直接在循环中,但容器可能在调用链中的某个地方被别名从循环体调用——这些是非常容易犯的错误,诊断起来绝对是残酷的。至少应该在每次迭代时打印容器的大小。
如果你有Linux操作系统,并且有一小部分代码重现了这个问题,你可以使用valgrind来帮助你找到这个问题
- CMake-按正确顺序将项目与C运行时对象文件链接
- 函数调用中参数的顺序重要吗
- 为什么不;名字在地图上是按顺序排列的吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 数到第n个楼梯的路(顺序无关紧要)
- Android NDK传感器向事件队列报告奇怪的间隔
- 优先顺序:智能指针和类析构函数
- 在循环中按顺序遍历成员变量
- 独立读取-修改-写入顺序
- 从文本文件中读取时钟时间和事件时间并进行处理
- WMI检测进程创建事件-c++
- EvtExportLogneneneba API正在将远程计算机的事件日志保存到远程PC本身.如何将其保存到主机
- QML按钮点击功能执行顺序
- C++中数据类型修饰符的顺序
- 当比特(而不是字节)的顺序至关重要时的持久性
- 给定顺序中的事件处理
- 对事件循环中槽的调用排队,由Qt按向后顺序处理
- 不可能的事件顺序
- Qt ++多个鼠标事件的不同顺序
- Lua元事件参数顺序