VE>try
VE>{
VE> f1(); // throws
VE>}
VE>finally
VE>{
VE> // Тут как понять, что летит исключение?
VE>}
VE>
Не надо там понимать ничего. finally нужен чтобы код выполнялся в любом случае, там абсолютно пофиг было исключение или нет.
VE>Если внутри finally сделать throw, то полетит новое исключение, если не сделать — то оригинальное (которое вылетело из f1()). VE>Соответственно, если обламалась попытка освободить ресурс — швыряем исключение, при этом старое пропадает.
static void Main()
{
try
{
throw new Exception("Исключение 1");
}
finally
{
throw new Exception("Исключение 2");
}
Запустите этот код, будете удивлены.
Re[35]: Зачем нужен сборщик мусора? Как жить без деструкторо
G>>Запустите этот код, будете удивлены.
VE>Ну поймало исключение 2, если не ловить, то окошко с исключением 2. VE>Я это должен был увидеть?
У меня в консоли выводятся оба ексепшена.
Re[26]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, drol, Вы писали:
D>А во-вторых, даже если поменять порядок объявлений, то всё равно деструктор для m_b вызовется. Потому как после исключения начнётся раскрутка стека, и в ней, разумеется, будет вызов этого самого деструктора.
Ух ты, оказывается C++ и так умеет! Здорово.
Никогда не сталкивался с исключениями в деструкторах, поэтому не знал, что C++ дает такие гарантии.
E>>Чтобы ее избежать, в C++ пришлось бы оборачивать вызов любого деструктора в try..catch, т.е. что-то типа:
D>Так вот оно и "оборачивается". Есть таблицы вызовов деструкторов автоматических объектов/данных-членов. Только механизма работает всего лишь до второго исключения из деструктора почему-то О чём и вопрос, собственно...
Ну попробуйте ответить на вопрос: порождается исключение A, начинается раскрутка стека. В процессе которой выбрасывается еще N исключений B1..Bn. Какое из исключений (A,B1,...,Bn) должно быть видно в программе?
E>>Хотя реальные причины мог бы озвучить, разве что, сам Страуструп.
D>Не знаю насчёт БС, но вот Вам точно не светит их когда-либо озвучить...
Да я и не претендовал
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[37]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, gandjustas, Вы писали:
G>У меня в консоли выводятся оба ексепшена.
Пардон. У меня было оконное (может и в нём? Просто не заметил?)
Но вопрос в другом. В finally может быть уже летящее исключение, а может и не быть.
Я хочу кинуть новое, если никакого не летит, и хочу оставить изначальное, если оно в полёте. Предложенный drol'ом try-catch внутри finally не сработает, ибо тогда летит только изначальное исключение из try (если вообще летит).
Если foo-bar пройдут нормально, то получим исключение при ошибки записи в файл, если foo кинет исключение, то закрытие будет производиться уже деструкторами — молча, но ничего от этого мы не потеряем, так как исключение всё же будет поймано и обработано (хотя и другое, то, которое вылетело изначально).
Re[37]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, gandjustas, Вы писали:
G>У меня в консоли выводятся оба ексепшена.
Тут срабатывает совсем другой сценарий. Дело в том, что обработчик UnhandledException у домена вызывается раньше, чем выполняются блоки finally вокруг места выброса исключения. Если бы мы ловили исключения выше по стеку, то мы поймали бы только "Исключение 2", а "Исключение 1" было бы потеряно. Так и в стандарте C# написано:
8.10 The try statement
....
If an exception is thrown during execution of a finally block, and is not caught within the same finally block, the exception is propagated to the next enclosing try statement. If another exception was in the process of being propagated, that exception is lost.
Кстати, эта формулировка была внесена в стандарт по моему предложению.
Re[38]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, VoidEx, Вы писали:
VE>Но вопрос в другом. В finally может быть уже летящее исключение, а может и не быть.
Для этого он и придуман.
VE>Я хочу кинуть новое, если никакого не летит, и хочу оставить изначальное, если оно в полёте. Предложенный drol'ом try-catch внутри finally не сработает, ибо тогда летит только изначальное исключение из try (если вообще летит).
А зачем вам тогда try/finally ? Бросайте исключение сразу после выполнения операции.
VE>Вообще, считаю, что в случае Си++ надо писать:
VE>
VE>Если foo-bar пройдут нормально, то получим исключение при ошибки записи в файл, если foo кинет исключение, то закрытие будет производиться уже деструкторами — молча, но ничего от этого мы не потеряем, так как исключение всё же будет поймано и обработано (хотя и другое, то, которое вылетело изначально).
А чем хуже писать^
using (var f1 = new file())
using (var f2 = new file())
using (var f3 = new file())
{
foo();
bar();
}
Поведение будет такоеже. Только все Dispose гарантированно вызовутся, деструкторы не нужны будут.
Может я что-то не ак понял?
Re[38]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, nikov, Вы писали:
N>Здравствуйте, gandjustas, Вы писали:
G>>У меня в консоли выводятся оба ексепшена.
N>Тут срабатывает совсем другой сценарий. Дело в том, что обработчик UnhandledException у домена вызывается раньше, чем выполняются блоки finally вокруг места выброса исключения. Если бы мы ловили исключения выше по стеку, то мы поймали бы только "Исключение 2", а "Исключение 1" было бы потеряно. Так и в стандарте C# написано:
N>
N>8.10 The try statement
N>....
N>If an exception is thrown during execution of a finally block, and is not caught within the same finally block, the exception is propagated to the next enclosing try statement. If another exception was in the process of being propagated, that exception is lost.
N>Кстати, эта формулировка была внесена в стандарт по моему предложению.
А каким образом UnhandledException узнает о двух исключениях?
Re[36]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, eao197, Вы писали:
E>Ну попробуйте ответить на вопрос: порождается исключение A, начинается раскрутка стека. В процессе которой выбрасывается еще N исключений B1..Bn. Какое из исключений (A,B1,...,Bn) должно быть видно в программе?
Ответ очевидный: должны быть видны все. Пойматься же должно в первом catch'е подходящем под какое-нибудь из цепочки. Раскрутка стека также должна нормально дорабатывать.
Вобщем как-то так...
Re[39]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, gandjustas, Вы писали:
G>А чем хуже писать^ G>
G>using (var f1 = new file())
G>using (var f2 = new file())
G>using (var f3 = new file())
G>{
G> foo();
G> bar();
G>}
G>
G>Поведение будет такоеже. Только все Dispose гарантированно вызовутся, деструкторы не нужны будут. G>Может я что-то не ак понял?
Ничем не хуже. Но в этом коде вылетит то исключение, которое будет выброшено последним. В коде Си++ то, которое вылетело первым (так как деструкторы уже не бросят).
drol утверждает, что Си++ в этом плане "отстой", а C# "рулит".
Показать ему, что это две стороны одной медали, мне не удалось. Он перешёл на хамство и мы закончили диалог.
Re[40]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, VoidEx, Вы писали:
VE>Ничем не хуже. Но в этом коде вылетит то исключение, которое будет выброшено последним.
Если Вам нужны другие исключения — пишите явный код на try/finally/catch/throw. И они у Вас будут безо всяких особых приседаний.
VE>В коде Си++ то, которое вылетело первым (так как деструкторы уже не бросят).
В случае C++ других исключений нет вообще.
В этом и разница. В C# можно элементарным образом получить хоть все цепочки исключений возникших в методе, а в C++ только одно, самое первое исключение.
VE>drol утверждает, что Си++ в этом плане "отстой", а C# "рулит".
Врёте. Мой тезис — не надо пихать нетривиальную очистку ресурса в деструктор.
Re[41]: Зачем нужен сборщик мусора? Как жить без деструкторо
Я с вами уже прекратил разговор. Я взял за правило не спорить с женской логикой, в которой целью стоит сказать последние слова типа "слив защитан" и считать себя после этого "победителем" в непонятно какой войне.
Re[41]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, drol, Вы писали:
D>В этом и разница. В C# можно элементарным образом получить хоть все цепочки исключений возникших в методе, а в C++ только одно, самое первое исключение.
В качестве домашнего упражнения:
Дана функция foo(), поймайте мне всю цепочку исключений, из неё вылетающих.
Отвечайте, когда сможете это сделать, остальное я буду игнорировать, мне надоело.
Re[42]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, VoidEx, Вы писали:
VE>Я с вами уже прекратил разговор.
А я с Вами ещё не закончил, уважаемый.
Так вот, если Вы желаете сослаться на какое-либо моё утверждение, то, пожалуйста, цитируйте его дословно, с контекстом, и с указанием прямой ссылки на соответствующий постинг. Бо я очень раздражаюсь, когда перевирают мои слова, и приписывают мне какие-то левые домыслы
Re[42]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, VoidEx, Вы писали:
D>>В этом и разница. В C# можно элементарным образом получить хоть все цепочки исключений возникших в методе, а в C++ только одно, самое первое исключение.
VE>Дана функция foo(), поймайте мне всю цепочку исключений, из неё вылетающих.
Гы Вылететь из функции может только одно единственное исключение. >1 их может возникнуть внутри функции, когда мы ловим их try/catch/finally/using. Для реализации моего утверждения, функция должна сложить все эти пойманные исключения в новое, отдельное, специальное исключение, и, в конце-концов, бросить его.
Если концепция Вам до сих пор непонятна, то вечером продемонстрирую...
Re[43]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, drol, Вы писали:
D>Здравствуйте, VoidEx, Вы писали:
VE>>Я с вами уже прекратил разговор.
D>А я с Вами ещё не закончил, уважаемый.
D>Так вот, если Вы желаете сослаться на какое-либо моё утверждение, то, пожалуйста, цитируйте его дословно, с контекстом, и с указанием прямой ссылки на соответствующий постинг. Бо я очень раздражаюсь, когда перевирают мои слова, и приписывают мне какие-то левые домыслы
В C# можно элементарным образом получить хоть все цепочки исключений возникших в методе, а в C++ только одно, самое первое исключение
Я уже привёл задачу. Меня не волнует, сколько из функции вылетает. Я выделил ключевые слова.
Без изменения функции этого сделать невозможно. Либо вы утверждаете обратное и приводите код, это подтверждающий, либо тогда признаёте, что были неправы. Имея доступ к коду функции, всю цепочку можно получить и в Си++, опровергайте тоже кодом, который будет принципиально неосуществим в Си++.
Re[43]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, drol, Вы писали:
D>Врёте. Мой тезис — не надо пихать нетривиальную очистку ресурса в деструктор.
равно как и не надо пихать нетривиальную очистку ресурса в одинокий finally
some_obj.open();
try {
.....
throw new VeryVeryVeryVeryImpotantException(); //которое ждут выше
.....
}
finally {
some_obj.close();//throw new OrdinaryException();
}
D>Если Вам нужны другие исключения — пишите явный код на try/finally/catch/throw. И они у Вас будут безо всяких особых приседаний.
этот случай — универсальный, и похоже реализуется во всех языках, тут говорить неочем.
Остается битва титанов(на тнт): Деструктор VS finally-одиночка Ни первое, ни второе не подходит для нетривиальной очистки ресурса
Тут можно ставить точку.
Но дальше идет моя субьективная точка зрения
деструктор удобен для тривиальной, хотябы, например, такой распространенной как освобождение мьютекса
зы
считаю освобождение мьютекса — тривиальной, т.к. из user mode его теоретически невозможно повредить, тут нельзя выдернуть флешку как в случае с файлом
Re[30]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, drol, Вы писали:
D>Конечно приводит, бо у Вас там два объекта. При выходе из блока вызывается деструктор для b. В нём происходит исключение. Стартует раскрутка стека. Она вызывает деструктор a. И в нём тоже происходит исключение. Только на сей раз это исключение при раскрутке стека, и строго согласно стандарту следует terminate()
Ну а где гарантии что в реальной программе такого не произойдет? Никаких — значит нафиг.
D>Если в Вашем примере оставить только один объект — всё будет нормально. То бишь "недодеструкченный" объект + продолжающая работать как ни в чём не бывало программа.
Т.е. в тепличных условиях может и будет работать.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока