考虑到Jon Kalb强大的异常安全代码来解决Cargill Widget示例,是什么阻止了编译器重新组织操作,从而使代码不是强烈异常安全的?
#include <algorithm> // std::swap
template< typename T1, typename T2 >
class Cargill_Widget
{
public:
Cargill_Widget& operator=( Cargill_Widget const& r_other )
{
using std::swap;
T1 temp_t1( r_other.m_t1 ); // may throw
T2 temp_t2( r_other.m_t2 ); // may throw
/* The strong exception-safety line */
swap( m_t1, temp_t1 ); // no throw
swap( m_t2, temp_t2 ); // no throw
return *this;
}
private:
T1 m_t1;
T2 m_t2;
};
是“编译器无法更改可观察行为”规则吗?
参考:
答案 0 :(得分:2)
你自己说过:编译器无法做任何事情 可能会修改可观察的行为。它有义务采取 可能的例外情况。潜在的限制 因此重新排序可能会产生重大负面影响 对优化的影响。实际上,有两种情况 考虑:编译器不知道发生了什么 被调用的函数,因此无法对它们进行重新排序,或者 编译器确实具有优化交叉的能力 翻译单位,在这种情况下,它通常能够 确定函数不会抛出(假设它不会),并且 因此重新排序就像忽略异常一样。或不 重新排序,如果抛出异常可能会导致更改 如果可以的话,可观察到的行为。
答案 1 :(得分:1)
任何优化都必须保留代码的可证明属性。否则任何代码都可以用一个没有做任何事情并且速度最快的程序替换。例外的影响是可证明属性的一部分。