Re[66]: ToString()
От: alexeiz  
Дата: 29.11.04 11:36
Оценка: 3 (1) -3 :))
Здравствуйте, Дарней, Вы писали:

Д>Здравствуйте, alexeiz, Вы писали:


A>>Зато исключение в Dispose может оставить программу в неопределенном состоянии, и это явно хуже, чем "обрушить прогу"


Д>А почему "в неопределенном состоянии"? Даже если один или несколько Dispose в пределах блока выбросит исключение, все остальные Dispose все равно будут вызваны. К сожалению, я не нашел данных, какое из этих исключений будет обработано

Д>Или ты что-то другое имел в виду?

A>>И кстати, не "обрушить", а вызвать terminate(), в котором ты волен произвести необходимые действия перед завершением (послать crash dump разработчику, например).


Д>Программа перестанет работать, не сохранив своих данных, не завершив сеанс работы и т.п. Крэш дамп конечно поможет разработчикам, но юзеру от этого легче не станет


Твоё недоумение скорее всего вызвано непониманием причин, по которым C++ обязывает программу аварийно завершиться при выбросе исключения при обработке другого исключения (скорее всего, когда деструктор выбрасывает). Почитай об этом в clc++.moderated или comp.std.c++. Здесь я, так как у меня нет времени это досконально разъяснять, скажу лишь, что проблеммы при выбросе исключений из деструкторов и из Dispose имеют один и тот же характер. Одна из таких проблем — это выброс исключения при обработке другого исключения, и она может случится, как с выбрасывающими десрукторами, так и с выбрасывающими Dispose. Эта проблемма не имеет удовлетворительного разрешения в том смысле, что невозможно обработать такую ситуацию и продолжить выполнение программы нормальным образом. Что-нибудь обязательно будет сломано в состоянии программы, ты на это можешь наткнуться и сразу вылететь, а можешь совсем не заметить, а можешь и произвести какие-нибудь деструктивные действия (вроде разрушения файлов пользователя при попытке сохранить его данные, эдак подложив пользователю своеобразную свинью).

Далее, тот факт, что .NET в этом случае позволяет тебе продолжить выполниние программы как ни в чём не бывало, является лишь непризнанием данной проблеммы как таковой дизайнерами .NET'а. Параллели между Dispose и деструкторами C++ очевидны. C++/CLI даже ставит их во взаимно однозначное соответствие. Почему дизайнеры .NET'а ничего криминального не увидели в продолжении выполнения программы в этом случае, для меня загадка. Скорее всего это было технически возможно сделать, и они решили "почему бы и нет?" Ведь в .NET программа не упадет при обращении к памяти с нуленым адресом, не перезапишет за пределы массива, т.е не сделает ничего такого, на что вполне способен в такой ситуации "wicked" C++. Поэтому они решили сделать .NET "более надёжным" и в данном случае. Но они не увидели принципиального недетерминированного поведения, access violation и buffer overrun всего лишь частные случаи которого.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.