Что мешает оптимизации компилятора переупорядочивать строго исключительный код?

Учитывая строго безопасный для исключений код Джона Калба для решения примера 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 ответа

Решение

Вы сами сказали: компилятор не может делать ничего, что могло бы изменить наблюдаемое поведение. И он обязан учитывать возможные исключения. Потенциально, ограничения на изменение порядка из-за этого могут оказать существенное негативное влияние на оптимизацию. Практически, есть два случая, чтобы рассмотреть: компилятор не знает, что происходит в вызываемых функциях, и поэтому не может переупорядочить по ним, или компилятор имеет возможность оптимизировать по всем единицам перевода, в этом случае, обычно он может определить, что функция не сгенерирует (при условии, что она не сработает), и, таким образом, изменить порядок в точности так, как если бы он игнорировал исключения. Или не изменять порядок, если создание исключения может вызвать изменение наблюдаемого поведения, если оно произошло.

Любая оптимизация должна сохранять доказуемые свойства кода. в противном случае любой код можно заменить программой, которая ничего не делает и работает максимально быстро. Эффекты исключений являются частью доказуемых свойств.

Другие вопросы по тегам