Почему std :: uncaught_exception изменится на std :: uncaught_exceptions?

Я только что заметил на

http://en.cppreference.com/w/cpp/error/uncaught_exception

что C ++ 17 заменит std::uncaught_exception(), который возвращает bool, с std::uncaught_exceptions(), который возвращает int,

Дополнение к стандарту, описывающему это здесь:

http://isocpp.org/files/papers/n4259.pdf

Это не дает обоснования, но говорит

[Примечание: когда uncaught_exceptions ()> 0, исключение может
привести к вызову std :: terminate () (15.5.1). — конец примечания]

что странно расплывчато

В чем причина этого изменения? Будут ли возможны многочисленные активные исключения в C ++ 17 или какой-либо будущей версии стандарта?

12

Решение

Бумага, которая представила это, была n4152, который имеет смысл (который обычно сводится к тому, чтобы «заставить ScopeGuard работать»)

Цитировать,

как задокументировано, по крайней мере, с 1998 года в «Гуру недели № 47», это означает, что код, который транзитивно вызывается из деструктора, который сам может быть вызван при разматывании стека, не может правильно определить, действительно ли он сам вызывается как часть разматывания. Как только вы раскручиваете любое исключение, uncaught_exception все выглядит как раскручивание, даже если существует более одного активного исключения.

А также

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

PS: вот пример того, как эта функция может быть реализована с использованием информации, специфичной для компилятора: https://github.com/panaseleus/stack_unwinding/blob/master/boost/exception/uncaught_exception_count.hpp

И для простого примера, где он используется, смотрите не дальше, чем «рекордный насос» boost.log (см. повышение / журнал / подробно / format.hpp а также повышение / Журнал / источники / record_ostream.hpp): это позволяет BOOST_LOG(lg) << foo(); войти в деструктор объекта охраны он создает, если foo не выдает, то есть, если число исключений в полете при вызове деструктора не больше, чем при вызове конструктора.

21

Другие решения

std :: uncaught_exception () только определяет, разматывается ли стек. В статье Херба Саттера он указывает, что это не означает, что существует активное исключение. Херб полагает, что это «почти» полезно. Я столкнулся с ситуацией, когда это действительно неоднозначно, что и привело меня к этому посту.

std :: uncaught_exceptions () указывается как возвращающее количество активных исключений, что на самом деле полезно.

-1

обратите внимание, что std :: uncaught_exception () все еще может быть полезен для debug / loginfo. Это может помочь определить, откуда возникло исключение. Однако я согласен функционально, это совершенно бесполезно.

-1
По вопросам рекламы [email protected]