我正在爲一個類編寫單元測試,以在沒有內存可用時測試插入。它取決於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
是一個函數,應在完成下一行之前完成函數的所有副作用。投擲是一個副作用。
獎勵點:如果正確答案是「是的重新排序可能發生」,是2號線足以解決它之間的內存屏障?
C/C++規範要求優化都具有「假設」優化沒有發生的結果。但是,這隻適用於實施,並且只有在計劃的正常執行中才需要。像POSIX SIGHUP和線程這樣的操作系統信號超出了C++規範,並且打破了「假設」的假設。就你而言,即使你稱之爲「signalReceived」,它也不是POSIX信號,不會成爲問題。 –