хъ
IK>ИМХО, а вот тут я с вами не согласен, относительно того что этот код нормальный.
Для С++ нормальный.
IK>Поясню свое несогласие: наличие такого кода говорит о неверно спроектированной архитектуре приложения.
В корне не согласен.
IK>Если взять хорошо продуманные библитотеки (.NET, VCL)
.Net — не библиотека.
IK> и посмотреть на то какие они исключения наружу передают, то увидим что у всех исключений есть базовый класс, так вот, на крайний случай его и надо ловить. Такой подход позволяет использовать, например Microsoft Application Blocks for .NET, а далее уж сами решайти, что с исключениями делать, оповещать о них или записывать куда-либо.
IK>
IK>try{
IK> //do some work
IK>}
IK>catch(Exception e){
IK> //do some cleanup
IK> throw;
IK>}
IK>
IK>Илья.
Для отчистки лучше использовать finally, однако и такой код ничего. Сам часто так пишу, но не нужно путать С++ с дотнетом.
Здравствуйте, Alexey Shirshov, Вы писали:
AS> Не согласен. AS> Следующий код вполне нормальный и очень часто встречается: AS>
AS> try{
AS> //do some work
AS> }
AS> catch(...){
AS> //do some cleanup
AS> throw;
AS> }
AS>
Я в этом случае сделаю обертку и не буду морочить голову ни себе, ни тому, кто будет этот код за мной поддерживать. Catch должен предполагать, что исключение поймано и наружу не выходит. Делать опять throw не здорово.
-- Всего хорошего!
-- Alex Alexandrov, e-mail: alex_alexandrov@fromru.com
Posted via RSDN NNTP Server 1.8 beta
It's kind of fun to do the impossible (Walt Disney)
почему это не будет? как настроишь, так и будет. Если конечно знаешь, как ошибку вызвать — и можешь запустить прогу из под отладчика.
T>И что делать — если приходит тестер — говорит — у меня падает....иногда T>А если это сервис? и падает он раз в 2 недели когда попадает в какую-либо незнакомую ситуацию (о простой порче памяти я не говорю) ? T>И воспроизвести не так-то просто?
T>Без DMP тут мало что поделать можно
логи, assert'ы и инварианты, конечно. Через dump тоже наверно можно, но это какой-то совсем уж садистический метод
Предлагаю не устраивать очередной holy war. Хоть я и не согласен с расстрелом в качестве наказания за catch(...), но....
У всех свои тара... прошу прощения, методы работы Кто-то искореняет в прогах STL, кто-то catch(...) — это уж кому как нравится.
хъ
_>Я в этом случае сделаю обертку и не буду морочить голову ни себе, ни тому, кто будет этот код за мной поддерживать.
Согласен, однако чем млохо это решиние (и чем оно отличается о написания тысячи оберток) я не понимаю.
_>Catch должен предполагать, что исключение поймано и наружу не выходит.
Здравствуйте, Alexey Shirshov, Вы писали:
AS> AS> _>Я в этом случае сделаю обертку и не буду морочить голову ни себе, ни AS> тому, кто будет этот код за мной поддерживать. AS> AS> Согласен, однако чем млохо это решиние (и чем оно отличается о AS> написания тысячи оберток) я не понимаю. AS> AS> _>Catch должен предполагать, что исключение поймано и наружу не AS> выходит. AS> AS> Почему? AS> AS> _>Делать опять throw не здорово. AS> AS> Почему?
Леш, ну мы же конструктивные люди...
Можно сделать и так, и так: работать будет. Тут дело просто в личных предпочтениях. Я выберу обертки, потому что уважаю Страуструпа. А он говорил: Resource Allocation Is Initialization. Освобождение ресурсов в __finally (а твой catch(...) {throw;} это всего лишь псевдоfinally), это стиль, навязанный нам Microsoft. Конструкторы-деструкторы выглядят изящнее (для меня). К тому же try/catch зависят от msvcrt.dll, а конструкторы-деструкторы работают всегда (имею в виду стековые переменные).
-- Всего хорошего!
-- Alex Alexandrov, e-mail: alex_alexandrov@fromru.com
Posted via RSDN NNTP Server 1.8 beta
It's kind of fun to do the impossible (Walt Disney)
Здравствуйте, Alexey Shirshov, Вы писали:
AS>Для С++ нормальный.
см ниже.
AS>В корне не согласен.
Опять же это все ИМХО, но хотелось бы узнать мнение. Чем хорош способ catch(...) в отличии от catch(Exception e)?
Если взглянуть на платфоры/библиотеки/технологии — .NET/VCL/COM, то в них есть интрефейс/класс для обработки ошибок.
1) Если программист использует catch (...), то получается он не знает какой фортиль выкинет его программа — ИМХО, это не хорошо и это просчеты в проектировании.
2) Если же он знает о поведении программы, то почему бы не написать класс исключения и с ним работать
плюсы:
а) "типизирование" ошибки
б) подробная информация
г) возможность использовать аналоги Microsoft Application Blocks for .NET для конкретной платформы и языка (для систем малого и среднего бизнеса это большой и жирный плюс)
минусы:
а) необходимость написания обертки для сторонних библиотек (но политика, некоторых компаний, не позволяет использовать внешние компоненты, чтобы не быть зависимыми от них и их багов, моя компания относиться к этим)
AS>.Net — не библиотека.
Согласен, просто хотел одним темином объединить .NET и VCL, впредь буду более корректным
AS>Для отчистки лучше использовать finally, однако и такой код ничего. Сам часто так пишу, но не нужно путать С++ с дотнетом.
Согласен, сам так делаю но речь шла catch, а с .NET не путаю, в теге ясно было указано что это код для C++
Вне сомнения, однако истина дороже.
_>Можно сделать и так, и так: работать будет. Тут дело просто в личных предпочтениях. Я выберу обертки, потому что уважаю Страуструпа. А он говорил: Resource Allocation Is Initialization. Освобождение ресурсов в __finally (а твой catch(...) {throw;} это всего лишь псевдоfinally), это стиль, навязанный нам Microsoft.
Хм. Спорное утверждение.
_>Конструкторы-деструкторы выглядят изящнее (для меня). К тому же try/catch зависят от msvcrt.dll, а конструкторы-деструкторы работают всегда (имею в виду стековые переменные).
Рантайм можно статические прилинковать.
И потом, дело не только в выделении ресурсов (к которым я сам предпочитаю писать обертки).
Например:
void some_class::foo()
{
try{
//do some work
}
catch(...){
//log the message - there was error during some_class::foothrow;
}
}
Это можно, конечно, обернуть в что-то вроде
void some_class::foo()
{
struct local{
bool _ok;
local(){_ok = false;}
do_work(){
//do some work
_ok = true;
}
~local(){
if (!_ok){
//log the message - there was error during some_class::foo
}
}
} l;l.do_work();
}
Однако первый вариант я почему-то предпочитаю больше.
хъ
IK>Если взглянуть на платфоры/библиотеки/технологии — .NET/VCL/COM, то в них есть интрефейс/класс для обработки ошибок.
И в STL есть, однако std::exception слишком мало покрывает.
IK>1) Если программист использует catch (...), то получается он не знает какой фортиль выкинет его программа — ИМХО, это не хорошо и это просчеты в проектировании.
Странно. А как можно быть увереным, что твой код не выкинет исключения, типа stack_overflow? Да и банальный AV — не редкость.
IK>2) Если же он знает о поведении программы, то почему бы не написать класс исключения и с ним работать IK>плюсы: IK> а) "типизирование" ошибки IK> б) подробная информация IK> г) возможность использовать аналоги Microsoft Application Blocks for .NET для конкретной платформы и языка (для систем малого и среднего бизнеса это большой и жирный плюс)
Согласен со всем, однако не все исключения, которые возникают в программе являются "нашими". Это верно для С++, но не верно для CLS-совместимого кода, в котором все исключения должны быть предком идного класса.
хъ
AS>>Для отчистки лучше использовать finally, однако и такой код ничего. Сам часто так пишу, но не нужно путать С++ с дотнетом. IK>Согласен, сам так делаю но речь шла catch, а с .NET не путаю, в теге ясно было указано что это код для C++
Вот именно, речь шла о catch в плюсах. А использовать в них std::exception для ловли всех исключений к сожалению невозможно.
... << RSDN@Home 1.1.0 stable >>
Re: OFFTOP: Re[7]: "Крик души"
От:
Аноним
Дата:
10.11.03 13:20
Оценка:
IK>минусы: IK> а) необходимость написания обертки для сторонних библиотек (но политика, некоторых компаний, не позволяет использовать внешние компоненты, чтобы не быть зависимыми от них и их багов, моя компания относиться к этим)
Т.е. как минимум не позволять расширятся приложению через плагины как у Adobe Photoshop, Visual Studio, MS Office ... или не использовать кодеки как у Windows Media Player или не давать возможности в свои документы вставлять OLE объекты кроме возможно избранных производителей...
Здравствуйте, Alexey Shirshov, Вы писали:
AS>Странно. А как можно быть увереным, что твой код не выкинет исключения, типа stack_overflow? Да и банальный AV — не редкость.
Это было год назад, сечас пишу под .NET, не знаю, возможно это магия или что-то еще, но мне как-то удавалось этого избежать на C++ особенно AV, возможно мне в этом помогали PurifyPlus и BoundsChecker ну и возможно играет роль "тип" приложения
AS>Согласен со всем, однако не все исключения, которые возникают в программе являются "нашими". Это верно для С++, но не верно для CLS-совместимого кода, в котором все исключения должны быть предком идного класса.
Согласен, но это уже получается дело вкуса, я бы в таком случае поставил бы несколько catch вместо catch(...),
а при необходимости наверх бы передавал бы свой класс исключения в котором сообщал детальную информацию об ошибке.
Снова повторюсь — это дело вкуса ... и методов проектирования
catch (Exception e)
{
}
catch (int i)
{
}
AS>Вот именно, речь шла о catch в плюсах. А использовать в них std::exception для ловли всех исключений к сожалению невозможно.
см выше
Здравствуйте, <Аноним>, Вы писали:
А>Т.е. как минимум не позволять расширятся приложению через плагины как у Adobe Photoshop, Visual Studio, MS Office ... или не использовать кодеки как у Windows Media Player или не давать возможности в свои документы вставлять OLE объекты кроме возможно избранных производителей...
А>Так? Так можно и из обоймы выпасть
Здравствуйте, Alexey Shirshov, Вы писали:
AS> AS> _>Конструкторы-деструкторы выглядят изящнее (для меня). К тому же AS> try/catch зависят от msvcrt.dll, а конструкторы-деструкторы работают AS> всегда (имею в виду стековые переменные). AS> AS> Рантайм можно статические прилинковать.
Я имел в виду те ситуации, когда от рантайма вообще избавиться задумано.
AS> И потом, дело не только в выделении ресурсов (к которым я сам AS> предпочитаю писать обертки). Например: AS>
AS> void some_class::foo()
AS> {
AS> try{
AS> //do some work
AS> }
AS> catch(...){
AS> //log the message - there was error during some_class::foo
AS> throw;
AS> }
AS> }
AS>
AS> AS> Это можно, конечно, обернуть в что-то вроде AS>
AS> void some_class::foo()
AS> {
AS> struct local{
AS> bool _ok;
AS> local(){_ok = false;}
AS> do_work(){
AS> //do some work
AS> _ok = true;
AS> }
AS> ~local(){
AS> if (!_ok){
AS> //log the message - there was error during some_class::foo
AS> }
AS> }
AS> } l;l.do_work();
AS> }
AS>
AS> AS> Однако первый вариант я почему-то предпочитаю больше.
Здесь согласен. Правда, если бы под Вижуалом нормально работала функция uncaught_exception(), то все можно было бы сделать куда красивее... В 7.0 она нормальная, не знаешь?
-- Всего хорошего!
-- Alex Alexandrov, e-mail: alex_alexandrov@fromru.com
Posted via RSDN NNTP Server 1.8 beta
It's kind of fun to do the impossible (Walt Disney)
IK> Согласен, но это уже получается дело вкуса, я бы в таком случае поставил бы несколько catch IK> вместо catch(...), IK> а при необходимости наверх бы передавал бы свой класс исключения в котором сообщал детальную IK> информацию об ошибке. IK> Снова повторюсь — это дело вкуса ... и методов проектирования IK>
IK>1) Если программист использует catch (...), то получается он не знает какой фортиль выкинет его программа — ИМХО, это не хорошо и это просчеты в проектировании.
А вы знаете все, что может выкинуть ваша программа? То есть все возможные ошибки? Значит ваши программы не допускают ошибок вообще, ведь раз вы знаете ошибки — вы их уже ликвидировали. Так? А вы уверены за чужие компоненты, за бесперебойную работу Windows?
У меня дома стоит 2000, запускаю апачи как сервис. Через час-полтора по непонятной причине хоть сервис и работает не загружается страница 127.0.0.1. Вот вы в курсе из-за чего такое может быть? И разработчики я уверен нет. А ошибка есть.
А вообще прекратили бы этот спор. На вашем же сайте четко и ясно сказано: оттестированность программы не имеет значения, главное показать ее функциональность. Так что нашли из-за чего спорить.
...Ei incumbit probatio, qui dicit, non qui negat...
Загляните на www.r-tt.com
Если заинтересует направление, пришлите, пожалуйста, более развернутое резюме на biounit@r-tt.com, желательно указать имеющийся опыт и наработки.
Здравствуйте, vitaly_spb, Вы писали:
_>А вообще прекратили бы этот спор. На вашем же сайте четко и ясно сказано: оттестированность программы не имеет значения, главное показать ее функциональность. Так что нашли из-за чего спорить.
Устойчивость и Supportability — это функции программы. Они должны быть реализованы, но могут не работать (оттестированность функций действительно значения не имеет).
АГ>Чем бы ты в данном случае заменил catch(...)? АГ>На каком основании?
Смотря что такое cleanup?
Если простая подчистка ресурсов так используйте смарт-поинтеры, классы-стражи, функторы и тп, которые в деструкторе все сделают. ( Их можно передавать и темплейтным параметром)
Если это какой-то частный роллбэк только и только в случаях ошибки, я бы не стал это запихивать в темплейтную функцию и пересмотрел бы дизайн решения.
Можно и в этом случае кстати попробовать предать какой-то функтор.
Самое плохое в единичном catch (...) — это глотание ошибки.
1)
а)Глотать _свои_ ошибки с моей точки зрения очень и очень плохо.
Я там видел в ветке народ предлагает для релиза ставить catch(...), так вот пусть лучше она упадет и создаст Dr.Watson log. чем
выдаст "Unknown error" и тем самым похоронит что там за ошибка была и почему.
Конечно, если речь идет о разовом заказе, можно отладить у клиента на его конфигурации и забыть про проект,
а если выпускать серийный продукт то каждый AV должен быть "радостью" для девелопера, так как позволяет улучшить продукт.
б) catch (...) ловит также и "аппаратные" исключения.
2) Глотать _чужие_ ошибки тоже не нужно. Часто такие catch(...) вызваны не просто ошибкой, а каким серьезным сбоем, могут быть утечки, порча памяти и т.п. Зачем все это богатство в своем процессе, если можно сделать внепроцессный компонент и шатдаунить процесс когда пошло что-то не так.
Но вариант с последующим throw и не глотает ошибки. Там есть throw.
Мы же отказались и от именно этого варианта в свое время из-за багофичи(асинхронных исключений) в VC 6.0 SP5 по причине которой в случаях, если определяется например два экземпляра объекта во внешней функции по отношению к исполняемой и происходит не-C++ исключение в catch(...), то деструктор второго объекта не вызывается.
Я пробовал методы и на основе исключений и на основе возврата кодов ошибок и пришел к выводу, что все условно.
на уровне одно модуля (подсистемы, группы класов или вообще методов одного класса) можно обрабатывать исключения, выше же лучше передавать информацию об ошибках и то по запросу.
(...) действительно ловить не стоит, если ты не знаешь кто будет пользоваться твоим совтом, пусть он сам его ловит.. Если знаешь, кто будет пользоваться то лучше поймать и вернуть false, например и Unknown error в описании, что бы верхняя программа могла прохромать дальше. Хотя это тоже относительно , короче все зависит от задачи и спор получается риторическим.
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)