Здравствуйте, drol, Вы писали:
E>>Ну попробуйте ответить на вопрос: порождается исключение A, начинается раскрутка стека. В процессе которой выбрасывается еще N исключений B1..Bn. Какое из исключений (A,B1,...,Bn) должно быть видно в программе?
D>Ответ очевидный: должны быть видны все.
Тогда может быть вы объясните, как это можно сделать, например, в следующем случае:
class B {
public : ...
~B() { if(some_condition) throw some_exception_t(); }
};
class C {
B m_b[ 10240 ];
...
};
void f() {
std::auto_ptr< C > c( new C() );
...
if( something_failed )
throw another_exception_t();
}
При раскрутке стека начнут вызываться деструкторы для 10K объектов B. Каждый из них выбрасывает свое исключение. Куда их все помещать? А что делать, если при их сохранении заканчивается свободная память?
D>Пойматься же должно в первом catch'е подходящем под какое-нибудь из цепочки.
Возвращаясь к тому же самому примеру. Функция f() вызывается из функции:
Допустим, что при раскрутке стека все исключения удалось сохранить и есть множество исключений, состоящее из одного исключения another_exception_t и 10K исключений some_exception_t. Для какого из экземпляров some_exception_t должен сработать catch в d()? Что делать с остальными экземплярами?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[40]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, VoidEx, Вы писали:
VE>Здравствуйте, 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>>Может я что-то не ак понял?
VE>Ничем не хуже. Но в этом коде вылетит то исключение, которое будет выброшено последним. В коде Си++ то, которое вылетело первым (так как деструкторы уже не бросят). VE>drol утверждает, что Си++ в этом плане "отстой", а C# "рулит". VE>Показать ему, что это две стороны одной медали, мне не удалось. Он перешёл на хамство и мы закончили диалог.
В вашем коде, если деструктор file вызывает close, и в нем может вылетет exception, то программа вообще может аварийно завершиться.
Если деструктор не вызывает close, то фактически ресурс (файл) окажется незакрытым.
Re[41]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, gandjustas, Вы писали:
VE>>Ничем не хуже. Но в этом коде вылетит то исключение, которое будет выброшено последним. В коде Си++ то, которое вылетело первым (так как деструкторы уже не бросят). VE>>drol утверждает, что Си++ в этом плане "отстой", а C# "рулит". VE>>Показать ему, что это две стороны одной медали, мне не удалось. Он перешёл на хамство и мы закончили диалог.
G>
G>В вашем коде, если деструктор file вызывает close, и в нем может вылетет exception, то программа вообще может аварийно завершиться. G>Если деструктор не вызывает close, то фактически ресурс (файл) окажется незакрытым.
Я в C++ном коде, если функции освобождения ресурсов выбрасывали исключения, применял такой подход: вызывал их в деструкторе обернутыми в try/catch. Т.е. исключения в деструкторе проглатывались.
При таком подходе пример VoidEx-а будет нормально работать и незакрытых ресурсов не будет оставаться.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[31]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, CreatorCray, Вы писали:
CC>Ну а где гарантии что в реальной программе такого не произойдет? Никаких — значит нафиг.
Идите и расскажите это Страуструпу
D>>Если в Вашем примере оставить только один объект — всё будет нормально. То бишь "недодеструкченный" объект + продолжающая работать как ни в чём не бывало программа. CC>Т.е. в тепличных условиях может и будет работать.
Повторяю ещё раз: с точки зрения стандарта C++ "недодеструкченность" допустима. И значит не является источником проблемы terminate()
Так что жду свежих предложений...
Re[42]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, gandjustas, Вы писали:
VE>>>Ничем не хуже. Но в этом коде вылетит то исключение, которое будет выброшено последним. В коде Си++ то, которое вылетело первым (так как деструкторы уже не бросят). VE>>>drol утверждает, что Си++ в этом плане "отстой", а C# "рулит". VE>>>Показать ему, что это две стороны одной медали, мне не удалось. Он перешёл на хамство и мы закончили диалог.
G>>
G>>В вашем коде, если деструктор file вызывает close, и в нем может вылетет exception, то программа вообще может аварийно завершиться. G>>Если деструктор не вызывает close, то фактически ресурс (файл) окажется незакрытым.
E>Я в C++ном коде, если функции освобождения ресурсов выбрасывали исключения, применял такой подход: вызывал их в деструкторе обернутыми в try/catch. Т.е. исключения в деструкторе проглатывались.
Я, наверное, тоже так делал бы.
E>При таком подходе пример VoidEx-а будет нормально работать и незакрытых ресурсов не будет оставаться.
Тогда практически нет смысла использовать явные close.
Re[43]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, gandjustas, Вы писали:
E>>При таком подходе пример VoidEx-а будет нормально работать и незакрытых ресурсов не будет оставаться. G>Тогда практически нет смысла использовать явные close.
Явный close -- наверное. А вот явный flush здесь бы был к месту.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[40]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, nikov, Вы писали:
G>>А каким образом UnhandledException узнает о двух исключениях?
N>Он вызывается два раза.
Но как? Чтобы понять что нужно вызвать UnhandledException нужно раскрутить стек и вызвать все finally. Или нет?
В качестве доп.инфы: в Smalltalk (и вероятно в других языках с продолжаемыми исключениями) при вызове исключения просто происходит поиск обработчика без раскрутки стека. Раскрутка стека (и вызов finally) происходит потом, если исключение не рестартовано. Т.е. два метода:
А если в блоке ensure: (типа "finally") выбросить исключение, то оно уйдёт на верх и finally в низу будет вызван уже после обработки этого нового исключения. Т.е. получится:
Здравствуйте, gandjustas, Вы писали:
G>Тогда практически нет смысла использовать явные close.
Здесь сетовали на то, что исключения из деструктора не кинуть, потому если всё пройдёт гладко, а ошибка будет в дектрукторе, — никто об этом не узнает.
Вместо close может быть commit, flush, что угодно, в зависимости от класса. При таком подходе если всё пройдёт гладко, то вызовется явный flush и выбросится исключение, если исключение вылетит раньше, то отработает "тихий" деструктор, а пользователь поймает исходное исключение.
Re[41]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, nikov, Вы писали:
G>>>А каким образом UnhandledException узнает о двух исключениях?
N>>Он вызывается два раза.
ANS>Но как? Чтобы понять что нужно вызвать UnhandledException нужно раскрутить стек и вызвать все finally. Или нет?
В процессе поиска подходящего блока catch блоки finally не выполняются. Они выполняются:
1) после того, как блок catch был найден и до того, как он был выполнен
2) или (если блок catch не был найден) после того, как выполнился обработчик UnhandledException
Re[42]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, nikov, Вы писали:
N>В процессе поиска подходящего блока catch блоки finally не выполняются. Они выполняются: N>1) после того, как блок catch был найден и до того, как он был выполнен N>2) или (если блок catch не был найден) после того, как выполнился обработчик UnhandledException
Во прикол. А есть обоснование такому поведению или "оно само так получилось"?
Здравствуйте, VoidEx, Вы писали:
VE>Извините, но продолжать с вами разговор я больше не хочу. VE>Упирайтесь рогом перед зеркалом и хамите туда же.
Не корми больше этого тролля.
Здравствуйте, eao197, Вы писали:
E>При раскрутке стека начнут вызываться деструкторы для 10K объектов B. Каждый из них выбрасывает свое исключение. Куда их все помещать? А что делать, если при их сохранении заканчивается свободная память?
Ну а что делают, когда, например, стек заканчивается ? Здесь то же самое: сами себе злые буратины писать такой код...
D>>Пойматься же должно в первом catch'е подходящем под какое-нибудь из цепочки. E>Допустим, что при раскрутке стека все исключения удалось сохранить и есть множество исключений, состоящее из одного исключения another_exception_t и 10K исключений some_exception_t. Для какого из экземпляров some_exception_t должен сработать catch в d()?
Для первого выброшенного этого типа.
E>Что делать с остальными экземплярами?
К ним должен быть обеспечен доступ из catch'а.
Re[30]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, drol, Вы писали:
E>>При раскрутке стека начнут вызываться деструкторы для 10K объектов B. Каждый из них выбрасывает свое исключение. Куда их все помещать? А что делать, если при их сохранении заканчивается свободная память?
D>Ну а что делают, когда, например, стек заканчивается ? Здесь то же самое: сами себе злые буратины писать такой код...
А к коду-то какие претензии? Мы же рассматриваем случай, когда из деструкторов можно бросать исключения. Вот они и бросаются -- почему же сразу "такой код"?
D>>>Пойматься же должно в первом catch'е подходящем под какое-нибудь из цепочки. E>>Допустим, что при раскрутке стека все исключения удалось сохранить и есть множество исключений, состоящее из одного исключения another_exception_t и 10K исключений some_exception_t. Для какого из экземпляров some_exception_t должен сработать catch в d()?
D>Для первого выброшенного этого типа.
А чем первое лучше любого другого? В частности, последнего?
E>>Что делать с остальными экземплярами?
D>К ним должен быть обеспечен доступ из catch'а.
Интересно, в каком языке программирования есть подобные catch-и?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[30]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, drol, Вы писали:
D>>>Пойматься же должно в первом catch'е подходящем под какое-нибудь из цепочки. E>>Допустим, что при раскрутке стека все исключения удалось сохранить и есть множество исключений, состоящее из одного исключения another_exception_t и 10K исключений some_exception_t. Для какого из экземпляров some_exception_t должен сработать catch в d()?
D>Для первого выброшенного этого типа.
Ну допустим. Тогда следующий вопрос: пусть в d() catch выполняет нормальную обработку и восстановление после исключения some_exception_t (т.е. из catch ничего не выбрасывается). Что тогда делать с another_exception_t, которое так же было в исходном множестве исключений?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[31]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, drol, Вы писали:
D>>>>Пойматься же должно в первом catch'е подходящем под какое-нибудь из цепочки. E>>>Допустим, что при раскрутке стека все исключения удалось сохранить и есть множество исключений, состоящее из одного исключения another_exception_t и 10K исключений some_exception_t. Для какого из экземпляров some_exception_t должен сработать catch в d()?
D>>Для первого выброшенного этого типа.
E>Ну допустим. Тогда следующий вопрос: пусть в d() catch выполняет нормальную обработку и восстановление после исключения some_exception_t (т.е. из catch ничего не выбрасывается). Что тогда делать с another_exception_t, которое так же было в исходном множестве исключений?
мое ИМХО:
должен быть задокументирован список исключений, которые может бросать метод/функция и кроме них ничего не должно вылетать
разумно использовать исключения для критических ошибок, после которых не предполагается продолжение работы
зы
читал интервью, где программист из google рассказывал о их стиле программирования на с++ (ссылку не могу найти), так вот говорит, что в своих классах не используют исключения вообще, только коды возврата.
Re[32]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, Adriano, Вы писали:
A>мое ИМХО: A>должен быть задокументирован список исключений, которые может бросать метод/функция и кроме них ничего не должно вылетать
В Java уже пробовали. В других языках эту ошибку повторять уже не хотят.
Да и в самой Java есть RuntimeException, который пролетает сквозь любые спецификации исключений.
A>разумно использовать исключения для критических ошибок, после которых не предполагается продолжение работы
Зачем же тогда исключения? std::abort() и всех делов.
A>зы A>читал интервью, где программист из google рассказывал о их стиле программирования на с++ (ссылку не могу найти), так вот говорит, что в своих классах не используют исключения вообще, только коды возврата.
У них официальный code style такой. Уже обсасывали эту тему на просторах форма "C++": здесь
Здравствуйте, eao197, Вы писали:
E>А к коду-то какие претензии? Мы же рассматриваем случай, когда из деструкторов можно бросать исключения. Вот они и бросаются -- почему же сразу "такой код"?
Потому что 10К нетривиальных автоматических объектов за раз.
E>А чем первое лучше любого другого? В частности, последнего?
"Чем лучше ? Чем армяне" (с) народ
E>>>Что делать с остальными экземплярами? D>>К ним должен быть обеспечен доступ из catch'а. E>Интересно, в каком языке программирования есть подобные catch-и?
Здравствуйте, eao197, Вы писали:
E>Ну допустим. Тогда следующий вопрос: пусть в d() catch выполняет нормальную обработку и восстановление после исключения some_exception_t (т.е. из catch ничего не выбрасывается). Что тогда делать с another_exception_t, которое так же было в исходном множестве исключений?
Ничего. catch ведь отработал => цирк уехал.
Логика примерно такая же, как в случае ловли исключения по базовому классу. Реально пойманный объект ведь может быть совсем другого типа, и даже многих других типов (приветствуем множественное наследование ), но catch рассматривает только контракт базового класса.
*Такими темпами я Вам скоро целый язык спроектирую
Re[32]: Зачем нужен сборщик мусора? Как жить без деструкторо
Здравствуйте, drol, Вы писали:
E>>А к коду-то какие претензии? Мы же рассматриваем случай, когда из деструкторов можно бросать исключения. Вот они и бросаются -- почему же сразу "такой код"?
D>Потому что 10К нетривиальных автоматических объектов за раз.
Офигеть. 10K объектов -- это вообще ничто.
Более того, аналогия с переполнение стека не корректна. Переполнение стека можно cпрогнозировать. И можно с ним бороться увеличением стека при порождении новых нитей приложения. В любом случае ситуация с переполнением стека будет легко поторяться -- при тех же самых входнах данных программа должна вылетать из-за переполнения стека. А вот с исключениями в деструкторе, когда у системы не хватает памяти, чтобы собрать их воедино, может получиться трудновоспроизводимое поведение: иногда приложение будет падать при 10K исключений, иногда не будет, а иногда будет падать при 5K.
E>>А чем первое лучше любого другого? В частности, последнего?
D>"Чем лучше ? Чем армяне" (с) народ
Т.е. четкого обоснования не будет?
Почему я не удивлен?
E>>>>Что делать с остальными экземплярами? D>>>К ним должен быть обеспечен доступ из catch'а. E>>Интересно, в каком языке программирования есть подобные catch-и?
D>Не знаю. Языков ведь навалом...
D>Как похожую (в плане доступности кучи исключений) фичу в C# сделать, я уже показывал.
Мы же сейчас не о C# говорим. Но меня интересует другое. Наличие N экземпляров исключения одного типа означает, что catch должен выглядеть как-то так:
Это означает, что все catch-и в C++ должны были бы выглядеть именно так.
D>Опять-таки InnerException ещё есть...
В C++?
В С++ в качестве исключения можно выбросить все, что угодно, хоть std::exception, хоть int, хоть char*. Может покажете, как к int или char* привязать InnerException?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.