|
Программирование >> Обобщенные обратные вызовы
численные исключопия проверке, имеется ли сгенерированное исключение в списке спецификации исключений. Чтобы понять, как должен работать компилятор, рассмотрим следующий код, в котором приведено тело одной из рассматриваемых функций - Nunc. Пример 13-4(а) int HuncO throw(A,в) { return juncO ; Компилятор должен сгенерировать код наподобие приведенного ниже, и расходы процессорного времени на его обработку точно такие же, как если бы вы ввели его самостоятельно (единственное облегчение - вам не надо набирать его самостоятельно; компилятор сам позаботится о его генерации). пример 13-4(6): обработанный компилятором код из примера 13-4(а) int HuncO try { return 3unc(); catchC A ) { throw; catch( в ) { throw; catchC ... ) { std::unexpected(); отсюда нет возврата! в лучшем случае здесь будет сгенерировано исключение А или В Вполне очевидно, что вместо того чтобы позволить компилятору оптимизировать код на основании информации о типах генерируемых исключений, спецификации исключений заставляют компилятор выполнять лишнюю работу по проверке сгенерированного исключения па предмет его принадлежности к списку спецификации. Копнем поглубже Большинство людей удивляет тот факт, что спецификации исключений могут вызвать снижение п ро и зводител ьн ости. Одна из причин такого снижения была только что продемонстрирована - это неявная генерация try/catch-блоков, хотя при использовании эффективных компиляторов соответствующие потери производительности невелики. Есть как минимум еще две причины снижения производительности программы из-за спецификаций исключений. Некоторые компиляторы автоматически делают невстраивасмыми функции, объявленные как inline, если у них имеются спецификации исключений. Это такая же эвристика, как и отказ некоторых компиляторов во встраиваемости функциям, которые имеют слишком много вложенных инструкций или содержащим циклы. Некоторые компиляторы вообще не в состоянии оптимизировать механизм исключений и добавляют автоматически сгенерированные try/catch-блоки даже к функциям, тела которых не генерируют исключений. Подведем итог данному обсуждению о снижении производительности программы при использовании спецификаций исключений, упомянув и об увеличении времени разработки -- из-за повышения степени связности. Например, удалив один тип из списка в спецификации исключений виртуальной функции базового класса, мы заставим компилятор ругаться на перекрытия этой функции в производных классах (разработкой которых занимались ваши коллеги). Попробуйте сделать это как-нибудь вечером в пятницу, а в понедельник утром посчитайте количество гневных писем, пришедших вам по электронной почте. В связи с эти вполне логичным представляется следующий вопрос. 5. Когда стоит использовать спецификацию исключений в функции? Почему вы используете (или не используете) эту возможность? Вот, пожалуй, наилучшие советы, рожденные опытом всего сообщества программистов на С++. > Рекомендация Совет №1. Никогда не указывайте спецификации исключений. Совет №2. Возможное исключение из совета №1 - это пустая спецификация исключений, но на вашем месте я бы избегал и ее. Опыт разработчиков Boost свидетельствует о том, что единственное место, где спецификация исключений может дать некоторое преимущество на некоторых компиляторах - это пустая спецификация исключений у невстраиваемой функции. Это невеселое заключение, но его стоит иметь в виду, если вы намереваетесь писать переносимый код, который будет использоваться на разных компиляторах. На практике все еще хуже, поскольку оказывается, что распространенные реализации С++ ухитряются по-разному обрабатывать спецификации исключений. Как минимум один популярный компилятор С++ (Microsoft - до текущей на момент написания эгой задачи версии 7.1 (2003)) выполняет синтаксический анализ спецификаций исключений, но в действительности не учитывает их в работе, превращая их по сути в некоторое подобие комментариев. Но это еще не все. Например, оптимизация, которую выполняет ком-пилятор Microsoft С++ 7.x, полагается на то, что спецификация исключений будет обеспечена внутри функции. Идея заключается в том, что если функция попытается сгенерировать нечто запретное, то внутренний обработчик остановит выполнение программы и управление никогда не вернется вызывающей функции. Так что если контроль возвращается вызывающей функции, то можно считать, что генерации исключений не было, а значит, в этом случае можно вообще убрать внешние try/catch-блоки. В таком компиляторе, который, с одной стороны, не обеспечивает выполнение спецификаций исключений, а с другой - опирается в своей работе на то, что они будут выполнены, - значение спецификации исключений throwO изменено. В результате вместо соответствующего ставдарту действия проверь меня и останови, если я нечаянно что-то сгенерирую выполняется следующее -- поверь мне, я никогда ничего не сгенерирую, так что можешь оптимизировать мой вызов . Поэтому будьте осторожны - даже при использовании пустой спецификации исключений ознакомьтесь с документацией на компилятор и проверьте, как именно он обрабагывает эту ситуацию. В противном случае поведение компилятора может оказаться для вас неприятным сюрпризом. Резюме Коротко: не утруждайте себя написанием спецификаций исключений. Более подробно: Спецификации исключений могу г привести к неожиданному изменению производительности программы, например, если компилятор не делает функции со спецификациями исключений встраиваемыми. Вызов функции unexpected во время выполнения программы - далеко не всегда желательный способ обработки ошибок, перехватить которые призвана спецификация исключений. В общем случае вы не в состоянии написать корректную спецификацию исключений для шаблона функции, поскольку не знаете, какие исключения могут сгенерировать типы, с которыми будет работать ваш шаблон. Когда данный материал не так давно был представлен мною на конференции, я спросил, кто из присутствующих использовал в своей практике спецификации исключений. Утвердительно ответила половина слушателей. Тогда один из слушателей сказал, что мне надо было бы спросить, сколько из этих людей теперь откажутся от них, что я и сделал. И поднялось примерно то же количество рук. Это весьма показательно. Разработчики библиотеки Boost, программисты мирового класса, имеющие большой опыт работы со спецификациями исключений, наилучшей стратегией считают отказ от этой возможности [ Boost ESJ. Многие люди с благими намерениями хотели видеть спецификации исключений в языке - вот почему они там оказались. А дальше ситуация разворачивалась, как во множестве анекдотов, повествующих о том, как волшебника, золотую рыбку или кого-то еще незадачливый герой просил исполнить его желание, но когда он получал желаемое, которое строго соответствовало его просьбе, вдруг оказывалось, что это совсем не то, чего хотел этот герсй. Будьте умеренны в своих желаниях - ведь вы можете получить то, что просите!
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |