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

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

# 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 код для них ничего не будет делать, когда выдается исключение.

0 ответов

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