C ++ исключение накладных расходов - PullRequest
32 голосов
/ 13 июля 2011

Почему разработчики встроенных платформ постоянно пытаются удалить использование C++ exceptions из их SDKs?

Например, Bada SDK предлагает следующий обходной путь для использования исключения, который выглядит как исключительно некрасиво:

 result
 MyApp::InitTimer()
 {
    result r = E_SUCCESS;

    _pTimer = new Timer;

    r = _pTimer->Construct(*this);
    if (IsFailed(r))
    {
        goto CATCH;
    }

    _pTimer->Start(1000);
    if (IsFailed(r))
    {
        goto CATCH;
    }

    return r;
 CATCH:
     return r;
 }

Каковы причины такого поведения?

Насколько я знаю, ARM компиляторы полностью поддерживают C++ exceptions, и этоне может быть на самом деле дело.Что-то еще?Действительно ли накладные расходы на использование исключений и раскручивание на ARM платформах действительно БОЛЬШОЕ , чтобы тратить много времени на такие обходные пути?

Может быть, что-то еще, о чем я не знаю?

Спасибо.

Ответы [ 6 ]

48 голосов
/ 13 июля 2011

Только мои 2 цента ...

Я консультируюсь исключительно по встраиваемым системам, большинство из которых работают в режиме реального времени и / или критически важны для безопасности / жизни. Большинство из них работают на 256 КБ флэш-памяти или ПЗУ или меньше - иными словами, это не"ПК-подобные" системы шин VME с 1 ГБ ОЗУ / флэш-памятью и 1 ГГц + ЦП. Это глубоко встроенные системы с ограниченными ресурсами.

Я бы сказал, что по крайней мере 75% продуктов, использующих C ++, отключают исключения в компиляторе (то есть код, скомпилированный с переключателями компилятора, которые отключают исключения). Я всегда спрашиваю почему. Хотите верьте, хотите нет, но самый распространенный ответ - это НЕ время выполнения или затраты памяти / затраты.

Ответы обычно представляют собой смесь:

  • «Мы не уверены, что знаем, как написать безопасный код исключения». Для них проверка возвращаемых значений более привычна, менее сложна и безопасна.
  • «Предполагая, что вы генерируете исключение только в исключительных случаях, это ситуации, когда мы все равно перезагружаемся [через их собственную процедуру обработки критических ошибок]»
  • Устаревшие проблемы с кодом (как упоминал jalf) - они работают с кодом, который появился много лет назад, когда их компилятор не поддерживал исключения или не реализовывал их правильно или эффективно

Кроме того - часто есть некоторая туманная неуверенность / страх по поводу накладных расходов, но почти всегда это не количественно / непрофессионально, это просто выбрасывается и принимается за чистую монету. Я могу показать вам отчеты / статьи, в которых говорится, что накладные расходы на исключения составляют 3%, 10% -15% или ~ 30% - выбирайте сами. Люди склонны цитировать цифру, которая отражает их собственную точку зрения. Почти всегда статья устарела, платформа / набор инструментов совершенно иные, и т. Д., Как говорит Родди, вы должны измерить себя на своей платформе.

Я не обязательно защищаю какую-либо из этих позиций, я просто даю вам реальную обратную связь / объяснения, которые я слышал от многих фирм, работающих с C ++ над встроенными системами, так как ваш вопрос «почему так много встроенных разработчики избегают исключений? "

19 голосов
/ 13 июля 2011

Я могу вспомнить пару возможных причин:

  • Более старые версии компилятора не поддерживали исключения, поэтому было написано много кода (и установлены соглашения), где исключения не используются
  • Исключения имеют свою стоимость, и они могут составлять до 10-15% от общего времени выполнения (они также могут быть реализованы так, что они практически не занимают время, но вместо этого используют довольно много памяти, что, вероятно, не Это очень желательно для встраиваемых систем)
  • Встраиваемые программисты, как правило, немного параноики по поводу размера кода, производительности и, что немаловажно, сложности кода. Они часто беспокоятся о том, что «расширенные» функции могут некорректно работать с их компилятором (и они часто тоже правы)
7 голосов
/ 13 июля 2011

Я думаю, что в основном это FUD, в наши дни.

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

Мера первая, Оптимизация вторая.

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

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

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

Редактировать:

@ jalf делает несколько хороших замечаний, и мой ответ выше был нацелен на связанный с этим вопрос, почему многие встроили Разработчики в целом все еще игнорируют исключения.

Но если разработчик SDK для конкретной платформы скажет " не используйте исключения ", вам, вероятно, придется пойти на это.Возможно, есть определенные проблемы с реализацией исключений в их библиотеке или компиляторе - или, возможно, они обеспокоены исключениями, возникающими в обратных вызовах, вызывающих проблемы из-за отсутствия безопасности исключений в их собственном коде.

5 голосов
/ 13 июля 2011

В других ответах высказывается мнение, противоположное "gotos is evil". Я делаю это сообщество вики, потому что я знаю, что это противоположное мнение будет разгорячено.

Любой программист, работающий в режиме реального времени, заслуживающий их внимания, знает об использовании goto. Это широко используемый и общепринятый механизм обработки ошибок. Многие жесткие среды программирования в реальном времени не поддерживают . Исключением являются концептуально только ограниченные версии setjmp и longjmp. Так зачем предоставлять исключения, когда основной механизм запрещен?

Среда может разрешать исключения, если всегда гарантируется, что все сгенерированные исключения будут обрабатываться локально. Вопрос в том, зачем это делать? Единственное оправдание в том, что gotos всегда злые. Ну, они не всегда злые.

5 голосов
/ 13 июля 2011

Такое отношение к исключениям не имеет ничего общего с производительностью или поддержкой компилятора, и все, что связано с идеей, что исключения усложняют код .

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

4 голосов
/ 13 июля 2011

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

См. Здесь страницу Бьярна Страурструпа, Зачем использовать исключения?

...