Форум: "Прочее";
Текущий архив: 2006.09.17;
Скачать: [xml.tar.bz2];
ВнизВопреки ругани форумчан Найти похожие ветки
← →
Loginov Dmitry © (2006-08-27 23:39) [0]Тайны конструкции try..finally..end
http://matrix.kladovka.net.ru/index.php?page=tryfinally
← →
guav © (2006-08-27 23:49) [1]IMHO:
Не стоит надеятся на существование "безопасных" конструкторов.
Деструкторы не должны выбрасывать исключений.
← →
Loginov Dmitry © (2006-08-27 23:54) [2]> guav © (27.08.06 23:49) [1]
> IMHO:
> Не стоит надеятся на существование "безопасных" конструкторов.
> Деструкторы не должны выбрасывать исключений.
Я и не надеюсь, а просто считаю объект безопасным, если вероятность возникновения исключения в его конструкторе ничтожно мала.
← →
Ketmar © (2006-08-27 23:58) [3]приемлемо. %-) собственно, я пишу обычно именно так, как рекомендовано в самом конце.
позволю себе дополнить: если уж развалился деструктор, то тут самое время орать "караул", гадить в лог и исчезать за горизонтом. опять же -- какие-то суперкритичные ресурсы, которые надо финализировать в любом случае -- это несколько другая сказка.
← →
Мефисто (2006-08-27 23:59) [4]Ух... Уже и статью накропал. Читаю...
← →
guav © (2006-08-28 00:02) [5]Abort это тоже исключение EAbort, и Assert сюда тоже не надо, а вот про Break и Continue можно было и вспомнить
"Если в блоке finally произойдет исключение, то выполнение конструкции будет прервано."
Проверим тебя:
procedure TForm1.Button1Click(Sender: TObject);
begin
try
raise Exception.Create("Something is wrong");
finally
try
raise Exception.Create("Something""s gone really wrong");
except
end;
raise Exception.Create("Something horrible happened");
end;
end;
Какие исключения увидит пользователь ?
← →
Мефисто (2006-08-28 00:17) [6]Ну, насчет нескольких вложений try...finally ни борланд в VCL, ни Тейксера с Пачекой не брезгуют.
← →
vuk © (2006-08-28 00:18) [7]
> Данная конструкция является пожалуй самой туманной конструкцией
> среди тех, что есть в Delphi.
>
Все непонятки, которые могут возникнуть по поводу try/finally разрешаются вдумчивым чтением руководства по языку.
← →
default © (2006-08-28 00:21) [8]guav © (28.08.06 00:02) [5]
у меня AV после "raise Exception.Create("Something""s gone really wrong");"
P.S. прости, какие нафиг тайны? это как слово "Хакер" в заглавии книги Фленова, быстро ты у него научился, однако
← →
isasa © (2006-08-28 00:24) [9]guav © (28.08.06 00:02) [5]
Тут есть маленький ньюанс. :)
Все правильно, до тех пор, пока выключен Integrated debugging.
А вот при включенном, увидим все три, по очереди.
← →
guav © (2006-08-28 00:29) [10]> у меня AV после "raise Exception.Create("Something""s gone
> really wrong");"
Это где ? Версия Delphi, OC ?
У себя проверил, работает как и должно.
← →
guav © (2006-08-28 00:31) [11]> guav © (28.08.06 00:02) [5]
>
> Тут есть маленький ньюанс. :)
Чтобы избежать его, я написал
> Какие исключения увидит пользователь ?
← →
Ketmar © (2006-08-28 00:31) [12]> [9] isasa © (28.08.06 00:24)
а без IDE и VCL -- два MessageBox()"а, потом "Application Error". %-)
← →
isasa © (2006-08-28 00:39) [13]guav © (28.08.06 00:31) [11]
А пишущий программу, не пользователь?
В примере нет прерываний. Все три raise выполнятся. Первый - штатно, сообщение второго подавлено пустым except, а третий, как всегда...
← →
guav © (2006-08-28 00:40) [14]Из [0]
P := nil;
P1 := nil;
try
...
GetMem(P, 255);
GetMem(P1, 2000000000);
finally
...
FreeMem(P);
FreeMem(P1);
end;
FreeMem не поднимает исключение если P = nil, но это не документировано, не стоит этим пользоваться.
← →
default © (2006-08-28 00:43) [15]guav © (28.08.06 00:29) [10]
Delphi 6, Me
вот в C# пашет
try
{
throw new Exception();
}
finally
{ //Получили исключение в try идём в finally на завершение
Console.WriteLine("1");
try
{ // ой, опять исключение, и в finally к тому же, что будет?
throw new InvalidOperationException();
}
catch
{ // ого, мы тут! значит первое исключение в finally
// не выводит его из строя!
Console.WriteLine("2");
}
// и мы даже тут!
Console.WriteLine("3");
}
// всяческие возгласы удивления добавлена для картинности,
// а не реального удивления
← →
default © (2006-08-28 00:44) [16]offtopic
в какой раз уже код с кривым форматированием постится? как лечить?
← →
guav © (2006-08-28 00:53) [17]offtopic
> в какой раз уже код с кривым форматированием постится? как
> лечить?
Студия табывставляет заместо пробелов (отучается в Tools>Options>Text Editor вроде), а форум не хочет их делать, .
← →
default © (2006-08-28 00:55) [18]guav © (28.08.06 00:53) [17]
что-то Дмитрий притих, неужели к написанию второй статьи приступил
← →
Ketmar © (2006-08-28 01:30) [19]> [14] guav © (28.08.06 00:40)
поэтому есть ReallocMem(), который ещё и переменную скинет в nil. %-)
← →
Loginov Dmitry © (2006-08-28 07:45) [20]Как всегда всем чего-то не нравится.
Ответьте тогда на такой вопрос: что в статье нужно изменить, чтобы ее было не стыдно показывать людям?
← →
Furyz © (2006-08-28 09:35) [21]Клевая статья , спасибо
← →
BiN © (2006-08-28 10:18) [22]
> vuk © (28.08.06 00:18) [7]
>
> Все непонятки, которые могут возникнуть по поводу try/finally
> разрешаются вдумчивым чтением руководства по языку.
Согласен.
Тема немного смахивает на "Секреты оператора сложения. Всё что вы хотели знать, но боялись спросить."
-)
← →
Ketmar © (2006-08-28 10:36) [23]да ладно вам. налетели, запинали... вполне приемлемо. убрать только страшилки о "загадочных инопланетных конструкциях" -- и вполне приемлемо.
← →
guav © (2006-08-28 12:22) [24]> что в статье нужно изменить, чтобы ее было не стыдно показывать
> людям?
В [5] я немного намекнул.
Польза сомнительна.
Если я что-л прочитаю в учебнике или статье я всё равно проверю по справке, а не буду путаться искать статьи. Если я вижу чьи то заблуждения, то, чтобы устранит их, я буду ссылаться на справку.
Статьи я буду уже искать если справка неясна или информация покажется не соответствующей действительности. При этом тут следует и самому всё проверять, а не только статьи читать.
← →
default © (2006-08-28 13:05) [25]Loginov Dmitry © (28.08.06 07:45) [20]
уже дано достаточно замечаний [5], [14], [19]
я бы добавил, что выносить за try строки вроде "FileStream := TFileStream.Create("MyFile.txt", fmOpenRead);" вообще говоря не стоит
если нет никаких внешних обработчиков исключения
ну, допустим пользователь указывает файл куда нужно дописать данные и неправильно набрал имя файла - что программа должна на этом остановиться? ясно, что могут быть в принципе случаи где можно и остановиться, но они редки, по крайней мере - надо об этом упомянуть
и на будущее - перед написанием статьи неплохо было бы изучить справку, по мне так - лучше бы перевод оттуда пусть и вольный кинуть чем твои самопальные пункты 1) 2)3)4)
← →
default © (2006-08-28 13:16) [26]не совсем точно выразился...
короче я к тому, что исключения могущие возникнуть в строках наподобие
"FileStream := TFileStream.Create("MyFile.txt", fmOpenRead);" вообще говоря надо обрабатывать, а не плевать на них, мол ресурс не занят и хрен с ним с исключением...
← →
guav © (2006-08-28 13:36) [27]> default ©
Вообще - исключения надо обрабатывать.
Но в VCL это уже сделано, причём централизованно, и в подобных слуаях мало причин вмешиваться. Результат такой обработки исключения EFOpenFileError - вполне адекватный.
Когда тербуется дополнительная обработка исключения, стоит применить except с raise; , чтобы сохранить исключение для дальнейшей обработки.
Если файл задаётся через диалог, то следует предусмотреть опцию FileMustExist, и тогда исключение - действительно будет дейсвительно нестадартной ситуацией.
Ещё, на тему обработки исключений, если функция вызывается сторонним API, выпускать из неё исключения не всегда безопасно, часто приходится обрабатывать их по месту возникновения.
← →
default © (2006-08-28 13:49) [28]guav © (28.08.06 13:36) [27]
не всегда исключения надо обрабатывать
← →
guav © (2006-08-28 13:53) [29]> [28] default © (28.08.06 13:49)
И это тоже.
Например исключение StackOverflowException :-)
← →
default © (2006-08-28 13:59) [30]guav © (28.08.06 13:53) [29]
ага:)
заглушать некоторые исключения и давать системе работать дальше как ни в чём не бывало это как давать стрелять бойцу с раненой рукой - может и в своего попасть
← →
Loginov Dmitry © (2006-08-28 18:36) [31]Исправил статейку. Выложил туда свой вариант перевода справки по try..finally. Постарался исправить так, чтоб все было без придирок.
Однако, до сих пор не могу понять, как можно было столько времени и себе и всем мозги тр..ть, когда всего-то нужно было прочитать справку. Просто полагал, что справку уже давно перевели всякие Фароновы, Архангельские, а фигушки! Наверно дословный перевод этой темы для них - слишком сложное дело. (вот Архангельския и нафигачил отсебятины).
Статья получилась суховатой, зато полезной (надеюсь :)).
← →
default © (2006-08-28 19:07) [32]Loginov Dmitry © (28.08.06 18:36) [31]
так лучше, ещё FreeMem поправь, см. [14]
"Часто бывают случаи, когда в программе должна выполниться определенная часть кода, несмотря на то, что выполняемый до нее код может быть прерван вследствие возникновения исключительной ситуации. "
в скобочках пометить(что также вследствие Exit, Break, Continue)
" Если в секции finally произошло исключение, и оно не было обработано внутри этой секции, то произойдет прерывание работы оператора try..finally, и любое исключение, возникшее в секции try, будет потеряно. В секции finally должна выполняться обработка любых возникающих в ней исключений, в противном случае будет невозможно выполнить обработку других исключений. "
вот это можно примером подкрепить, с потерей и без
try
try
raise EZeroDivide.Create("");
finally
// теряем исключение EZeroDivide
// для избежания этого нужно обрабатывать исключение EOverflow
raise EOverflow.Create("");
end;
except
on EZeroDivide do ShowMessage("EZeroDivide");
on EOverflow do ShowMessage("EOverflow");
end;
try
try
raise EZeroDivide.Create("");
finally
try
raise EOverflow.Create("");
except
end;
end;
except
on EZeroDivide do ShowMessage("EZeroDivide");
on EOverflow do ShowMessage("EOverflow");
end;
правда тут придётся предполагать знание блоков try except end;
можно написать статью о try except end и в настоящей статье сослаться на неё, если хочешь
хотя, как уже упоминали, ценность подобных статей невелика...
посмотри у Рихтера разделы по защищённым блокам и обработки исключений
там куча примеров, вот если напишешь что-то подобное только с содержательными примерами на Delphi, то ценность такой статьи резко возрастёт
← →
Loginov Dmitry © (2006-08-28 19:23) [33]> так лучше, ещё FreeMem поправь,
Так уже ж подправил вроде бы.
> вот это можно примером подкрепить, с потерей и без
Это же перевод справки. Как-то некорректно будет вносить в него дополнительные изменения.
← →
default © (2006-08-28 19:30) [34]Loginov Dmitry © (28.08.06 19:23) [33]
"Как-то некорректно будет вносить в него дополнительные изменения."
это не изменение, а примеры подкрепляющие сказанное, так быстрее доходит, думаю дойдёт даже если о try except end не слыхали
← →
guav © (2006-08-28 19:50) [35]Вспомнил кстати, как я делал, когда объектов было действительно много.
Инициализация и финализация всех в куче требовала внимательности.
Тода я решил использовать такой вариант.ObjectList := TObjectList.Create;
try
//...
SomeObject := TSomeClass.Create;
try
ObjectList.Add(SomeObject);
except
SomeOjbect.Free;
raise;
end;
...
SomeObject2 := TSomeClass2.Create;
try
ObjectList.Add(SomeObject2);
except
SomeOjbect2.Free;
raise;
end;
...
finally
ObjectList.Free;
end;
, но потом отказался от этого, решив что вложенные try лучше и разбив функцию на части.
← →
Loginov Dmitry © (2006-08-28 19:54) [36]Опять этот мифический TObjectList. Сколько их всего в Delphi?
Где-то один находил, так он оказался тем же TList, только все параметры Pointer были изменены на TObject. Название модуля уже не помню. Искал поиском с помощью файл-менеджера.
← →
default © (2006-08-28 20:03) [37]мда
← →
guav © (2006-08-28 20:22) [38]> он оказался тем же TList, только все параметры Pointer были
> изменены на TObject.
не только...
cмотри исходники... читай справку... в данном случае хватит одного из двух.
> [37] default © (28.08.06 20:03)
и не говори
← →
Ketmar © (2006-08-28 21:07) [39]> [36] Loginov Dmitry © (28.08.06 19:54)
ничего мифического. rtfs contnrs.pas.
← →
Loginov Dmitry © (2006-08-29 02:52) [40]Всего какой-то простенький, невзрачный, перекрытый метод Notify, но зато сколько функциональности!!!
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2006.09.17;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.039 c