Re[28]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.08.08 07:04
Оценка:
Здравствуйте, 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() вызывается из функции:
void d() {
  try {
    f();
  }
  catch( const some_exception_t & x ) {
    ...
  }
}

Допустим, что при раскрутке стека все исключения удалось сохранить и есть множество исключений, состоящее из одного исключения another_exception_t и 10K исключений some_exception_t. Для какого из экземпляров some_exception_t должен сработать catch в d()? Что делать с остальными экземплярами?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[40]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.08.08 08:34
Оценка:
Здравствуйте, 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>Показать ему, что это две стороны одной медали, мне не удалось. Он перешёл на хамство и мы закончили диалог.

VE>file f1, f2, f3;
VE>foo();
VE>bar();
VE>f1.close(); f2.close(); f3.close();
VE>

В вашем коде, если деструктор file вызывает close, и в нем может вылетет exception, то программа вообще может аварийно завершиться.
Если деструктор не вызывает close, то фактически ресурс (файл) окажется незакрытым.
Re[41]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.08.08 09:39
Оценка:
Здравствуйте, gandjustas, Вы писали:

VE>>Ничем не хуже. Но в этом коде вылетит то исключение, которое будет выброшено последним. В коде Си++ то, которое вылетело первым (так как деструкторы уже не бросят).

VE>>drol утверждает, что Си++ в этом плане "отстой", а C# "рулит".
VE>>Показать ему, что это две стороны одной медали, мне не удалось. Он перешёл на хамство и мы закончили диалог.

G>
VE>>file f1, f2, f3;
VE>>foo();
VE>>bar();
VE>>f1.close(); f2.close(); f3.close();
VE>>
G>

G>В вашем коде, если деструктор file вызывает close, и в нем может вылетет exception, то программа вообще может аварийно завершиться.
G>Если деструктор не вызывает close, то фактически ресурс (файл) окажется незакрытым.

Я в C++ном коде, если функции освобождения ресурсов выбрасывали исключения, применял такой подход: вызывал их в деструкторе обернутыми в try/catch. Т.е. исключения в деструкторе проглатывались.

При таком подходе пример VoidEx-а будет нормально работать и незакрытых ресурсов не будет оставаться.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[31]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: drol  
Дата: 11.08.08 10:18
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Ну а где гарантии что в реальной программе такого не произойдет? Никаких — значит нафиг.


Идите и расскажите это Страуструпу

D>>Если в Вашем примере оставить только один объект — всё будет нормально. То бишь "недодеструкченный" объект + продолжающая работать как ни в чём не бывало программа.

CC>Т.е. в тепличных условиях может и будет работать.

Повторяю ещё раз: с точки зрения стандарта C++ "недодеструкченность" допустима. И значит не является источником проблемы terminate()

Так что жду свежих предложений...
Re[42]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.08.08 10:28
Оценка:
Здравствуйте, eao197, Вы писали:

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


VE>>>Ничем не хуже. Но в этом коде вылетит то исключение, которое будет выброшено последним. В коде Си++ то, которое вылетело первым (так как деструкторы уже не бросят).

VE>>>drol утверждает, что Си++ в этом плане "отстой", а C# "рулит".
VE>>>Показать ему, что это две стороны одной медали, мне не удалось. Он перешёл на хамство и мы закончили диалог.

G>>
VE>>>file f1, f2, f3;
VE>>>foo();
VE>>>bar();
VE>>>f1.close(); f2.close(); f3.close();
VE>>>
G>>

G>>В вашем коде, если деструктор file вызывает close, и в нем может вылетет exception, то программа вообще может аварийно завершиться.
G>>Если деструктор не вызывает close, то фактически ресурс (файл) окажется незакрытым.

E>Я в C++ном коде, если функции освобождения ресурсов выбрасывали исключения, применял такой подход: вызывал их в деструкторе обернутыми в try/catch. Т.е. исключения в деструкторе проглатывались.

Я, наверное, тоже так делал бы.

E>При таком подходе пример VoidEx-а будет нормально работать и незакрытых ресурсов не будет оставаться.

Тогда практически нет смысла использовать явные close.
Re[43]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.08.08 10:30
Оценка:
Здравствуйте, gandjustas, Вы писали:

E>>При таком подходе пример VoidEx-а будет нормально работать и незакрытых ресурсов не будет оставаться.

G>Тогда практически нет смысла использовать явные close.

Явный close -- наверное. А вот явный flush здесь бы был к месту.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[40]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 11.08.08 10:51
Оценка:
Здравствуйте, nikov, Вы писали:

G>>А каким образом UnhandledException узнает о двух исключениях?


N>Он вызывается два раза.


Но как? Чтобы понять что нужно вызвать UnhandledException нужно раскрутить стек и вызвать все finally. Или нет?

В качестве доп.инфы: в Smalltalk (и вероятно в других языках с продолжаемыми исключениями) при вызове исключения просто происходит поиск обработчика без раскрутки стека. Раскрутка стека (и вызов finally) происходит потом, если исключение не рестартовано. Т.е. два метода:
main
    [ self except ] 
        on: Error 
        do: [:ex | Transcript show: 'handled'; cr]
        
except
    [ Error raiseSignal ]
        ensure: [Transcript show: 'finally'; cr]


Если вызвать "main", то будет напечатано

handled
finally

А если в блоке ensure: (типа "finally") выбросить исключение, то оно уйдёт на верх и finally в низу будет вызван уже после обработки этого нового исключения. Т.е. получится:

handled
<<Unhandled exception>>
finally

http://www.smalltalk.ru << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[43]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: VoidEx  
Дата: 11.08.08 11:11
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Тогда практически нет смысла использовать явные close.


Здесь сетовали на то, что исключения из деструктора не кинуть, потому если всё пройдёт гладко, а ошибка будет в дектрукторе, — никто об этом не узнает.
Вместо close может быть commit, flush, что угодно, в зависимости от класса. При таком подходе если всё пройдёт гладко, то вызовется явный flush и выбросится исключение, если исключение вылетит раньше, то отработает "тихий" деструктор, а пользователь поймает исходное исключение.
Re[41]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: nikov США http://www.linkedin.com/in/nikov
Дата: 11.08.08 11:40
Оценка: 8 (2)
Здравствуйте, Andrei N.Sobchuck, Вы писали:

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


G>>>А каким образом UnhandledException узнает о двух исключениях?


N>>Он вызывается два раза.


ANS>Но как? Чтобы понять что нужно вызвать UnhandledException нужно раскрутить стек и вызвать все finally. Или нет?


В процессе поиска подходящего блока catch блоки finally не выполняются. Они выполняются:
1) после того, как блок catch был найден и до того, как он был выполнен
2) или (если блок catch не был найден) после того, как выполнился обработчик UnhandledException
Re[42]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 11.08.08 11:54
Оценка:
Здравствуйте, nikov, Вы писали:

N>В процессе поиска подходящего блока catch блоки finally не выполняются. Они выполняются:

N>1) после того, как блок catch был найден и до того, как он был выполнен
N>2) или (если блок catch не был найден) после того, как выполнился обработчик UnhandledException

Во прикол. А есть обоснование такому поведению или "оно само так получилось"?
http://www.smalltalk.ru << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[36]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: CreatorCray  
Дата: 11.08.08 12:59
Оценка: +1 -1
Здравствуйте, VoidEx, Вы писали:

VE>Извините, но продолжать с вами разговор я больше не хочу.

VE>Упирайтесь рогом перед зеркалом и хамите туда же.
Не корми больше этого тролля.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[32]: Оффтоп
От: Кэр  
Дата: 11.08.08 14:59
Оценка:
Ник, хорош детей учить программировать Засылай лучше мне CV на мыло, я его передам куда надо. Мы тут Google борем, прикольно учавствовать
Re[29]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: drol  
Дата: 12.08.08 12:49
Оценка:
Здравствуйте, eao197, Вы писали:

E>При раскрутке стека начнут вызываться деструкторы для 10K объектов B. Каждый из них выбрасывает свое исключение. Куда их все помещать? А что делать, если при их сохранении заканчивается свободная память?


Ну а что делают, когда, например, стек заканчивается ? Здесь то же самое: сами себе злые буратины писать такой код...

D>>Пойматься же должно в первом catch'е подходящем под какое-нибудь из цепочки.

E>Допустим, что при раскрутке стека все исключения удалось сохранить и есть множество исключений, состоящее из одного исключения another_exception_t и 10K исключений some_exception_t. Для какого из экземпляров some_exception_t должен сработать catch в d()?

Для первого выброшенного этого типа.

E>Что делать с остальными экземплярами?


К ним должен быть обеспечен доступ из catch'а.
Re[30]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.08.08 13:36
Оценка:
Здравствуйте, 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]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.08.08 13:38
Оценка:
Здравствуйте, 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]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: Adriano  
Дата: 12.08.08 14:57
Оценка:
Здравствуйте, 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]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.08.08 15:17
Оценка:
Здравствуйте, Adriano, Вы писали:

A>мое ИМХО:

A>должен быть задокументирован список исключений, которые может бросать метод/функция и кроме них ничего не должно вылетать

В Java уже пробовали. В других языках эту ошибку повторять уже не хотят.
Да и в самой Java есть RuntimeException, который пролетает сквозь любые спецификации исключений.

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


Зачем же тогда исключения? std::abort() и всех делов.

A>зы

A>читал интервью, где программист из google рассказывал о их стиле программирования на с++ (ссылку не могу найти), так вот говорит, что в своих классах не используют исключения вообще, только коды возврата.

У них официальный code style такой. Уже обсасывали эту тему на просторах форма "C++": здесь
Автор: night beast
Дата: 02.07.08


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[31]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: drol  
Дата: 12.08.08 20:29
Оценка:
Здравствуйте, eao197, Вы писали:

E>А к коду-то какие претензии? Мы же рассматриваем случай, когда из деструкторов можно бросать исключения. Вот они и бросаются -- почему же сразу "такой код"?


Потому что 10К нетривиальных автоматических объектов за раз.

E>А чем первое лучше любого другого? В частности, последнего?


"Чем лучше ? Чем армяне" (с) народ

E>>>Что делать с остальными экземплярами?

D>>К ним должен быть обеспечен доступ из catch'а.
E>Интересно, в каком языке программирования есть подобные catch-и?

Не знаю. Языков ведь навалом...

Как похожую (в плане доступности кучи исключений) фичу в C# сделать, я уже показывал. Опять-таки InnerException ещё есть...
Re[31]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: drol  
Дата: 12.08.08 20:41
Оценка:
Здравствуйте, eao197, Вы писали:

E>Ну допустим. Тогда следующий вопрос: пусть в d() catch выполняет нормальную обработку и восстановление после исключения some_exception_t (т.е. из catch ничего не выбрасывается). Что тогда делать с another_exception_t, которое так же было в исходном множестве исключений?


Ничего. catch ведь отработал => цирк уехал.

Логика примерно такая же, как в случае ловли исключения по базовому классу. Реально пойманный объект ведь может быть совсем другого типа, и даже многих других типов (приветствуем множественное наследование ), но catch рассматривает только контракт базового класса.

*Такими темпами я Вам скоро целый язык спроектирую
Re[32]: Зачем нужен сборщик мусора? Как жить без деструкторо
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 13.08.08 06:49
Оценка:
Здравствуйте, drol, Вы писали:

E>>А к коду-то какие претензии? Мы же рассматриваем случай, когда из деструкторов можно бросать исключения. Вот они и бросаются -- почему же сразу "такой код"?


D>Потому что 10К нетривиальных автоматических объектов за раз.


Офигеть. 10K объектов -- это вообще ничто.

Более того, аналогия с переполнение стека не корректна. Переполнение стека можно cпрогнозировать. И можно с ним бороться увеличением стека при порождении новых нитей приложения. В любом случае ситуация с переполнением стека будет легко поторяться -- при тех же самых входнах данных программа должна вылетать из-за переполнения стека. А вот с исключениями в деструкторе, когда у системы не хватает памяти, чтобы собрать их воедино, может получиться трудновоспроизводимое поведение: иногда приложение будет падать при 10K исключений, иногда не будет, а иногда будет падать при 5K.

E>>А чем первое лучше любого другого? В частности, последнего?


D>"Чем лучше ? Чем армяне" (с) народ


Т.е. четкого обоснования не будет?
Почему я не удивлен?

E>>>>Что делать с остальными экземплярами?

D>>>К ним должен быть обеспечен доступ из catch'а.
E>>Интересно, в каком языке программирования есть подобные catch-и?

D>Не знаю. Языков ведь навалом...


D>Как похожую (в плане доступности кучи исключений) фичу в C# сделать, я уже показывал.


Мы же сейчас не о C# говорим. Но меня интересует другое. Наличие N экземпляров исключения одного типа означает, что catch должен выглядеть как-то так:
catch( const std::exception ** exceptions )
{
  for( const std::exception ** p = exceptions; *p; ++p )
    // Обработка очередного экземпляра исключения.
    ...
}


Это означает, что все catch-и в C++ должны были бы выглядеть именно так.

D>Опять-таки InnerException ещё есть...


В C++?
В С++ в качестве исключения можно выбросить все, что угодно, хоть std::exception, хоть int, хоть char*. Может покажете, как к int или char* привязать InnerException?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.