2013-03-21 99 views
3

鉴于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; 
}; 

是它的“编译器不能改变观察到的行为”的规则?

参考:

回答

2

你自己说的:编译器不能做任何 可能会修改观察到的行为。并且必须考虑到 可能的例外情况。潜在地,重新排序的限制 因为这可能会对优化产生显着的负面影响 。实际上,有两种情况可以考虑:编译器不知道被调用的函数中发生了什么,所以不能重新排序,或者编译器确实有能力优化跨越 的翻译单元,在这种情况下,它通常可以通过 确定该函数不会抛出(假设它不会),因此 就会重新排序,就好像它忽略了异常一样。或者不重新排序,如果抛出异常,则可能会导致 可观察行为发生变化。

1

任何优化必须保留代码的可证明属性。否则任何代码都可以用一个什么都不做并且速度最快的程序代替。例外的影响是可证物业的一部分。