Использование флагов noexcept и компилятора, отключающих исключения

вступление

Во встроенном C++, и особенно в системах реального времени, нет необходимости обрабатывать исключения, и если система выйдет из строя, обычно мы даем ей сбой. Каждый сбой - это ошибка программиста, которую необходимо исправить. Таким образом, в выпуске нет необходимости обрабатывать исключения.

проблема

Использование спецификатора noexcept позволяет значительно уменьшить размер двоичных файлов и повысить производительность. Таким образом, каждая функция stl внутри функции с noexcept будет вызывать перегрузку noexcept, если она доступна. Но использование этого спецификатора ограничено и имеет множество ограничений (наследование, подпись виртуальных функций, совместимость). Если вы измените исходный код без надлежащей интеграции, возникнут ошибки типа looser throw specifier for....

Флаг исключения (например, g ++ -fno-exceptions) заменяет только все throw на abort и может немного уменьшить размер стека.

вопрос

Есть ли какие-либо передовые методы использования спецификатора или флагов noexcept в случае, когда необходимо обновить устаревший код (до C++ 11), повысить производительность и уменьшить размер двоичных файлов? На данный момент я вижу только один способ - добавить noexcept к каждой функции.

компиляторы (arm-none-eabi-g ++, компилятор C++ MSVC), C++ 14

Этот текст каким-то образом утверждает, что исключение = ошибка программиста = сбой. Также использование noexcept эквивалентно переносу тела функции в блок try ... catch, улавливающий любые исключения и вызывающий std::terminate. Таким образом, noexcept не гарантирует отсутствия исключений.

user7860670 11.04.2018 12:47

То, что что-то вызвало исключение, не означает, что произойдет сбой. Это просто означает, что произошло что-то «исключительное». Например, IOBlockException (как в Java) означает, что данных нет ... и если они не обнаружены, то ЭТО ошибка.

UKMonkey 11.04.2018 12:48

@UKMonkey Во встроенном ПО обычно не требуется исключительной ситуации: это еще один поток выполнения для тестирования и сертификации, и его особенно сложно протестировать (поскольку исключения не являются структурированным программированием).

Adrian Maire 11.04.2018 12:51
Usage of noexcept specifier can significantly reduce the size of binary files and increase performance Вы обнаружите, что это может повлиять на размер двоичного файла; но в производительности нет никаких изменений.
UKMonkey 11.04.2018 12:52

@AdrianMaire «тестирует и сертифицирует» только потому, что он встроен, не означает, что он должен быть сертифицирован; то, что он не встроен, не означает, что он не нуждается в сертификации. Возбуждение исключения можно легко протестировать с помощью тестовых объектов так же, как вы тестируете не исключение.

UKMonkey 11.04.2018 12:55

"Использование спецификатора noexcept может значительно уменьшить размер двоичных файлов и повысить производительность." - у вас есть источник последнего? Я не являюсь экспертом по встроенным технологиям, но не думаю, что сильно теряется производительность, особенно в потоке без исключений. Если только некоторые предсказатели / программные кеши не сброшены дополнительным кодом. Но замеров не видел.

luk32 11.04.2018 12:56

@VTT, блок try-catch, который вызывает terminate, требует раскрутки стека до того, как будет перехвачено исключение, что требует запуска любых деструкторов с побочными эффектами. Когда исключение выйдет из функции noexcept, компилятору разрешено но не обязательно выполнять любую раскрутку стека. Он может просто закончиться вместо того, чтобы раскручиваться до точки захвата. Таким образом, эти два случая не совсем эквивалентны (и один может производить меньший более быстрый код).

Jonathan Wakely 11.04.2018 13:14

@JonathanWakely Вот почему я написал «эквивалентный», а не просто «равный» или «такой же».

user7860670 11.04.2018 13:17

@VTT, и в моем комментарии написано «не совсем эквивалентно», поэтому другие читатели не могут ошибочно подумать, что вы имели в виду именно это. В нормальном английском языке как синонимы могут использоваться эквиваленты и одинаковые и одинаковые.

Jonathan Wakely 11.04.2018 13:19
2
9
1 222
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

In this way, every stl function inside a function with noexcept will call noexcept overload if it is available.

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

Уменьшение размера из-за маркировки функции noexcept связано с тем, что компилятору не нужно генерировать код для раскрутки стека и обработки исключений, он может просто завершить работу. Но если вы используете -fno-exceptions, компилятор также не должен генерировать код для раскрутки стека и обработки исключений, поэтому вы должны получить те же преимущества (без необходимости добавлять noexcept куда-либо).

Are there any good practices how to use noexcept specifier or flags, in the case where it is necessary to upgrade legacy code (before c++11), increase performance and reduce size of binaries?

Хорошая практика состоит в том, чтобы добавлять noexcept только к функциям, которые, как вы знаете, определенно не может генерировать и которые никогда не будут изменены на throw, или же, если вы определенно хотите, чтобы они вызывали std::terminate в случае возникновения исключения.

Это не значит, что нужно добавлять его во все функции.

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

Итак, предпочтительнее ли использовать флаг компилятора, когда нет необходимости обрабатывать исключения?

Smit Ycyken 11.04.2018 13:01

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

Jonathan Wakely 11.04.2018 13:16

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