2009-06-04 2 views
15

В общем, я обычно использую try/catch для кода, который имеет несколько точек отказа, для которых ошибки имеют общий обработчик.Использование блоков try/catch в C++

По моему опыту, это обычно код, который квалифицирует ввод или контекст перед выполнением какого-либо действия или вывода после выполнения какого-либо действия.

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

Я хотел бы понять немного больше об основании для выше рекомендаций:

  • Какова природа накладных расходов?
  • Есть ли последние рекомендации по разработке, которые касаются рекомендуемого использования (или избежания) блоков try/catch?
  • Насколько быстрые процессоры и более современные компиляторы смягчают проблемы с помощью try/catch?

Заранее спасибо за помощь,

AJ

+0

Я не уверен, что понял вопрос. Вы беспокоитесь о производительности блоков try/catch? Или спрашивать об использовании try/catch для обработки проверки ввода или что? – jalf

+0

Dupe of http://stackoverflow.com/questions/43253/measuring-exception-handling-overhead-in-c и многие другие – 2009-06-04 16:18:37

ответ

0

По моему опыту, самая большая проблема с попыткой/уловом блоками мы часто пытаемся поймать исключения слишком обобщенно. Например, если я завершаю свою основную функцию блоком try/catch, который ловит (...), я в основном пытаюсь не разрешить моей программе сбой b/c отброшенного исключения.

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

+1

Вы всегда можете поймать и перебросить. Примечание. Если исключение выходит из main(), оно определяется реализацией, когда стек разматывается (так что деструкторы не могут быть вызваны). Таким образом, я всегда поймаю (...) и запишусь в main и повторно брошу, чтобы получить сообщение об ошибке Windows. –

5

К вашему второму вопросу: общие рекомендации here, Herb Sutter также дает довольно хороший совет here.

6

Я нашел a technical report on C++ performance (pdf предупреждение), который включает раздел об исключениях. Вам это может показаться интересным. У меня были коллеги, которые считали, что на каждой инструкции в блоке try/catch есть накладные расходы, но этот технический отчет, похоже, не поддерживает эту идею.

+0

Эта ссылка сейчас перенаправляется на http://www.stroustrup.com/ :( –

+0

@ShawnChin: Так и было. Я нашел новую ссылку, а также понял, что я неправильно присвоил бумагу. Я исправил сообщение. –

+0

Более поздняя версия этого отчета доступна здесь: http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf –

0

В большинстве языков, входящих и выходящих из блока try/catch с помощью обычных методов, бесплатно, это происходит только тогда, когда возникает исключение, которое обработчик исключений ищет, где обрабатывать исключение.

2

Зависит от компилятора. Почему бы вам не написать простую функцию с блоком try-catch и аналогичным без него и сравнить сгенерированный машинный код?

17

В C++, стоимость зависит от реализации. В общем, существует два способа реализации исключений:

Первый - это подход «стола». Компилятор строит набор таблиц для поиска, в том месте, где выбрано исключение, куда идти.Когда генерируется исключение, он должен искать каждую таблицу в стеке вызовов до тех пор, пока не найдет что-то, что поймает это исключение. Так как это все время выполнения, вход или выход из try catch не производит штраф (хороший), но бросание исключения включает в себя потенциально много запросов, создающих гораздо более медленный бросок. Я лично предпочитаю неплатежи за блокировку catch, потому что исключения должны быть очень редким обстоятельством. Это также сделало бы исполняемые файлы более крупными, если они должны были хранить таблицы.

Секундомер «код». Каждый раз, когда код входит в блок catch try, концептуально расположение блока помещается в стек. Это приводит к стоимости при входе и выходе из блока try-catch, однако при возникновении исключения механизм выполнения может быстро выскочить из стека, чтобы найти, куда идти. Итак, бросание исключений (намного?) Быстрее, но вход в блок теперь имеет стоимость. Помещение блока catch try в замкнутом петле низкого уровня может привести к значительным накладным расходам.

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

0

В C++ вы не должны использовать блоки try/catch для выполнения очистки. Вместо этого вы можете использовать шаблоны для выполнения инвентаризации ресурсов.

auto_ptr являются один [плохо] Пример

синхронизации замков, где вы храните мьютекс в качестве переменной состояния, и использовать локальные переменные (шаблоны или регулярные классы) для выполнения .acquire() /. Выпуск() методы.

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

Смежные вопросы