Должен ли компилятор всегда удалять блок try-catch, если доказано, что он не выбрасывает - PullRequest
0 голосов
/ 08 октября 2018

Учтите это:

#include <stdexcept>

template <class T>
void F(T &&t) {
    try {
        t(); 
    } catch(...) {}
}

int main() {
    F([]() noexcept {});             // Call 1
    F([]{});                         // Call 2
    F([]{ throw std::exception{}; });// Call 3
}

Я нашел на clang++-6.0 с флагами -std=c++17, независимо от заданных мной флагов оптимизации, всегда нет __gxx_personality и кода обработки исключений для Call 1.

Можно ли полагаться на такую ​​оптимизацию при использовании другого компилятора?Я считаю только C++11 и выше.

1 Ответ

0 голосов
/ 08 октября 2018
Спецификатор

noexcept был добавлен в c ++ 11 в качестве замены для throw().Это гарантирует, что функция не сгенерирует .Разница между ним и throw() заключается в том, что при noexcept, если функция на самом деле выбрасывает , стек может быть только не получен , что не было в случае с предыдущим (стек всегда становится бесполезным).Это позволяет проводить больше оптимизаций, например, полностью исключая обработку исключений.

Подводя итог, можно сказать, что компилятор принимает решение об исключении обработки исключений, но с noexcept у него нет никаких причин не делать этого.так что , что было действительно трудно определить в другом случае.

...