【发布时间】:2013-07-05 18:23:47
【问题描述】:
我正在为一个类编写一个单元测试,以在没有可用内存时测试插入。它依赖于nbElementInserted 在insert_edge 返回后递增的事实。
void test()
{
adjacency_list a(true);
MemoryVacuum no_memory_after_this_line;
bool signalReceived = false;
size_t nbElementInserted = 0;
do
{
try
{
a.insert_edge( 0, 1, true ); // this should throw
nbElementInserted++;
}
catch(std::bad_alloc &)
{
signalReceived = true;
}
}
while (!signalReceived); // this loop is necessary because the
// memory vacuum only prevents new memory
// pages from being mapped. so the first
// allocations may succeed.
CHECK_EQUAL( nbElementInserted, a.nb_edges() );
}
现在我想知道这两种说法中哪一种是正确的:
- 可能会发生重新排序,在这种情况下,
nbElementInserted可以在insert_edge引发异常之前递增,这会使我的情况无效。可能会发生重新排序,因为如果两行被置换,用户的可见结果是相同的。 - 无法重新排序,因为
insert_edge是一个函数,并且该函数的所有副作用都应该在转到下一行之前完成。投掷是一种副作用。
奖励点:如果正确答案是“是的,可能会发生重新排序”,那么两行之间的内存屏障是否足以修复它?
【问题讨论】:
-
C/C++ 规范要求优化都具有“好像”优化没有发生的结果。但是,这仅在执行时才实用,并且仅在程序的常规执行中需要。诸如 POSIX SIGHUP 和线程之类的操作系统信号超出了 C++ 规范,并打破了“as-if”假设。在您的情况下,即使您将其称为
signalReceived,它也不是 POSIX 信号,也不会成为问题。
标签: c++ exception try-catch compiler-optimization