В любом случае, намекнуть компилятору оптимизировать деструктор scope_failure, когда нет исключений? - PullRequest
0 голосов
/ 23 октября 2018

Рассмотрим следующий код:

# include <exception>
# include <cassert>

# define INLINE [[gnu::always_inline]]

template <class F>
class scope_failure
{
    F f;

public:
    constexpr INLINE scope_failure(F &&func) noexcept: 
        f{std::move(func)}
    {}

    INLINE ~scope_failure() noexcept
    {
        if (std::uncaught_exceptions())
            f();
    }
};

void F1() {
    scope_failure s{[]() noexcept { assert(false); }};
}

int main() {
    F1();
}

Как вы можете видеть, в void F1() не выдается исключение, поэтому ~scope_failure ничего не должен делать, и его даже можно оптимизировать, потому чтоэто имеет значение только в контексте, в котором выдается исключение.

Я скомпилировал код, используя clang++-6.0 -std=c++17 -S, и оказалось, что этой оптимизации не происходит.Я хочу спросить, есть ли способ сделать это?

Редактировать, объяснение мотивации для этой оптимизации:

ИМХО, это очень важная оптимизация.Он разрешает zero-cost abstraction для кода, который использует scope_success или scope_failure для выполнения cleanup или для создания assertion в нем, то есть части contract programming.

. Более того,если компиляторы могут оптимизировать этот код, они также могут оптимизировать код зарегистрированного destructor для exception-handling кода для обратного вызова, напр.удалите if в scope_failure и выполните зарегистрированную функцию обратного вызова напрямую или удалите регистрацию scope_success для exception-handling кода, поскольку они ничего не сделают, когда выдается исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...