Re[17]: Какие у исключений проблемы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.11.14 07:08
Оценка:
Здравствуйте, jazzer, Вы писали:
J>Ну так это обеспечивают обычные RAII guards. (Естественно, предполагается, что смена часиков на стрелочку не бросит исключения.)
Не вижу в этом ничего естественного. Давайте попробуем придумать операцию, которая не бросит исключения вообще никак-никак, а не просто "ну, скорее всего вы вряд ли получите в ответ window station is shutting down". Мне что-то вообще ничего в голову не приходит.

J>для этого у guard-а делается флажок, который взводится, если все хорошо (обычно метод называется commit), и тогда деструктор идет по сценарию commit, а иначе (по умолчанию) — по сценарию rollback.

Это изоморфно ручному вызову commit перед каждым выходом из scope. Для минимально нелинейной логики отслеживание этого руками — тот ещё геморрой.

J>Для этого, очевидно, нужно предпринять специальные усилия (т.е. какие-то параллельные структуры) по сохранению сути того, что мы собирались сделать и не смогли.

J>Самое простое — очередь задач, где обломившаяся задача не удаляется из очереди и ее можно попробовать запустить еще раз или что-то с ней сделать.

J>Другой вариант — сохранять сами исключения (у меня есть игрушечный вариант на С++11, если интересно, выложу куда-нть) и всю необходимую информацию прямо в них.

J>Но тут, понятно, нас всегда подстерегают ошибки выделения памяти.
Это частный случай. В том смысле, что если мы выбрасываем исключение, то у нас оно уже есть, и для упаковки его в nested exception доп.места не надо. А если память кончилась при попытке выкинуть исключение — то вместо него мы выбрасываем тот самый статический экземпляр out-of-memory, который мы заботливо прикопали при старте программы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: Какие у исключений проблемы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.11.14 07:09
Оценка:
Здравствуйте, AlexRK, Вы писали:
ARK>Кстати, пара "антонимов" — это всего лишь вырожденный случай некоторой цепочки вычислений, в которой должны быть гарантированно вызваны некоторые методы в некотором порядке.
Мне одному между строк мерещится термин "монада"?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: Какие у исключений проблемы?
От: AlexRK  
Дата: 12.11.14 07:20
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

ARK>>Кстати, пара "антонимов" — это всего лишь вырожденный случай некоторой цепочки вычислений, в которой должны быть гарантированно вызваны некоторые методы в некотором порядке.
S>Мне одному между строк мерещится термин "монада"?

Я не большой знаток монад (сам недавно просил пояснить, что это такое ), но, насколько я понял, монады это не совсем то.
Я говорю о чем-то вроде контрактов на каналы в Singularity. Например, для работы с файлами контракт может быть навроде "Open[1] -> (Read | Write)[0..] -> Close[1]".
Для упрощенной модели ресурсов хватит только "открыть-закрыть", причем "закрыть" можно выполнять автоматом.
Re[19]: Какие у исключений проблемы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.11.14 08:14
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


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

ARK>>>Кстати, пара "антонимов" — это всего лишь вырожденный случай некоторой цепочки вычислений, в которой должны быть гарантированно вызваны некоторые методы в некотором порядке.
S>>Мне одному между строк мерещится термин "монада"?

ARK>Я не большой знаток монад (сам недавно просил пояснить, что это такое ), но, насколько я понял, монады это не совсем то.

А по мне так как раз ровно оно: они же введены как раз для того, чтобы гарантировать "вызов некоторых методов в некотором порядке". Например, что для Future мы сначала дожидаемся окончания отложенного вычисления, а уже потом потребляем значение.
ARK>Я говорю о чем-то вроде контрактов на каналы в Singularity. Например, для работы с файлами контракт может быть навроде "Open[1] -> (Read | Write)[0..] -> Close[1]".
ARK>Для упрощенной модели ресурсов хватит только "открыть-закрыть", причем "закрыть" можно выполнять автоматом.
Эта модель уже реализована в С++, где "открыть" — это конструктор, а "закрыть" — деструктор.
Как мы только что обсудили, этой модели недостаточно для покрытия интересных нам сценариев, когда стадия финализации может обломиться.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: Какие у исключений проблемы?
От: jazzer Россия Skype: enerjazzer
Дата: 12.11.14 08:27
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

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

J>>Ну так это обеспечивают обычные RAII guards. (Естественно, предполагается, что смена часиков на стрелочку не бросит исключения.)
S>Не вижу в этом ничего естественного. Давайте попробуем придумать операцию, которая не бросит исключения вообще никак-никак, а не просто "ну, скорее всего вы вряд ли получите в ответ window station is shutting down". Мне что-то вообще ничего в голову не приходит.

А чего ты тогда хочешь? Что входит в твое понятие антонима? Просто попытка вызвать обратное действие, независимо от того, будет она успешной или нет?
Ну так это делается путем подавления ошибок в деструкторе (и то же самое было бы в любом другом случае).
А если нет, и ты хочешь получить сообщение об ошибке курсора, то что предлагается делать в случае цепочки антонимов?
Скажем, один, восстанавливает курсор, а второй гасит лампочку на девайсе, подключенном по COM-порту.

Плюс возврат ошибки в случае отвалившегося антонима — это очень сомнительная практика сама по себе.
Типа ты вызываешь функцию для долгого расчета интеграла, а в ответ получаешь ошибку "не смогли восстановить курсор-стрелочку".

J>>для этого у guard-а делается флажок, который взводится, если все хорошо (обычно метод называется commit), и тогда деструктор идет по сценарию commit, а иначе (по умолчанию) — по сценарию rollback.

S>Это изоморфно ручному вызову commit перед каждым выходом из scope. Для минимально нелинейной логики отслеживание этого руками — тот ещё геморрой.

Ну еще есть scope(exit), scope(success), scope(failure) — ты их имеешь в виду?

S>Это частный случай. В том смысле, что если мы выбрасываем исключение, то у нас оно уже есть, и для упаковки его в nested exception доп.места не надо. А если память кончилась при попытке выкинуть исключение — то вместо него мы выбрасываем тот самый статический экземпляр out-of-memory, который мы заботливо прикопали при старте программы.


По Стандарту С++11 — никаких гарантий, увы, нет. Даже std::current_exception() может вернуть bad_exception, если не удалось создать копию текущего исключения (если таковая понадобилась).
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[18]: Какие у исключений проблемы?
От: jazzer Россия Skype: enerjazzer
Дата: 12.11.14 08:30
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


J>>Ну так это обеспечивают обычные RAII guards. (Естественно, предполагается, что смена часиков на стрелочку не бросит исключения.)


ARK>А если бросит?


а смысл в этом какой?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[20]: Какие у исключений проблемы?
От: AlexRK  
Дата: 12.11.14 08:35
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>А по мне так как раз ровно оно: они же введены как раз для того, чтобы гарантировать "вызов некоторых методов в некотором порядке". Например, что для Future мы сначала дожидаемся окончания отложенного вычисления, а уже потом потребляем значение.


А можно через монады организовать, например, циклы? Чисто гипотетически, конечно, но все равно: сперва "открыть", потом произвольное количество раз сначала "читать", потом "писать", и в самом конце "закрыть".

S>Эта модель уже реализована в С++, где "открыть" — это конструктор, а "закрыть" — деструктор.

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

Ну да, этого недостаточно. Я, кстати, не могу придумать нормального варианта, как быть в такой ситуации, то бишь если происходит крах при финализации. Похоже, единственное, что можно сделать — как-то передать ошибку наверх. Но при этом должны выполниться и все остальные деструкторы. Правда, ошибка в первом деструкторе может повлиять и на остальные... В общем, хз, как лучше. Конечно, лучше всего статически запретить любые ошибки в финализаторах, но это не сработает для внешних сущностей — баз данных, сетевых соединений и т.п.
Re[19]: Какие у исключений проблемы?
От: AlexRK  
Дата: 12.11.14 08:37
Оценка:
Здравствуйте, jazzer, Вы писали:

J>а смысл в этом какой?


Смысл тот же, какой и при обработке любой другой ошибки. Например сообщить, что важное действие выполнить не удалось.
Re[20]: Какие у исключений проблемы?
От: jazzer Россия Skype: enerjazzer
Дата: 12.11.14 08:39
Оценка:
Здравствуйте, AlexRK, Вы писали:

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


J>>а смысл в этом какой?


ARK>Смысл тот же, какой и при обработке любой другой ошибки. Например сообщить, что важное действие выполнить не удалось.


См. мой ответ Синклеру рядом
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[19]: Какие у исключений проблемы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.11.14 08:50
Оценка: +1
Здравствуйте, jazzer, Вы писали:

J>А чего ты тогда хочешь? Что входит в твое понятие антонима? Просто попытка вызвать обратное действие, независимо от того, будет она успешной или нет?

Антоним — это то действие, которое я заложил в алгоритм.
Вот, например, банальная штука на воображаемом языке:
using(var stream = openSerializationStream())
{
  stream.Write("Customer", customer);
  if (customer.Status < Status.Ready)
    return; // #1 - no data saved for the not ready customers

  var orders = Orders.GetOrders(customer) ;
 
  if (orders.Length==0)
    return; #2 - nothing to save
  stream.Write("OrdersTotal", orders.Total(o=>o.Amount));
  foreach(var o in orders)
    if (o.Status != Status.Ready)
       break; # 3 - list all ready orders, then exit
    else
       stream.Write("Order #"+o.Id, o);
}

Я хочу двух вещей:
1. Чтобы у меня буфер сбрасывался на диск не после каждой операции, но при выходе из scope. То есть я не хочу ни добавлять принудительный flush к Write (страдает перформанс), ни руками дописывать stream.Flush() перед каждым return/break/} (чревато ошибками).
2. Чтобы о об ошибках записи я узнавал не из чтения побитого файла, а из вылетающего исключения.

В С++ сие невозможно, т.к. единственное, что гарантированно сработает при выходе — это деструктор, а в деструкторе бросать исключения нельзя.

J>Скажем, один, восстанавливает курсор, а второй гасит лампочку на девайсе, подключенном по COM-порту.

Это — вопрос, требующий проработки. У меня нет всех деталей задачи про курсор и лампочку; потому мне сложно сказать, какие гарантии тут нужны. Потому что по ком-порту может быть не лампочка подключена, а электронный замок, перекрывающий дверь шлюза. И подавление исключения означает "да хрен с ним, с этим шлюзом — нехай экипаж задохнётся".

J>Плюс возврат ошибки в случае отвалившегося антонима — это очень сомнительная практика сама по себе.

J>Типа ты вызываешь функцию для долгого расчета интеграла, а в ответ получаешь ошибку "не смогли восстановить курсор-стрелочку".
Это потому, что вам не жалко курсор. А что, если функция для долгого расчёта не смогла результат в файл сохранить. Вы тоже сочтёте сомнительной практику как-то намекнуть об этом вызывающему коду?

J>Ну еще есть scope(exit), scope(success), scope(failure) — ты их имеешь в виду?

А что это? Может и их.

J>По Стандарту С++11 — никаких гарантий, увы, нет. Даже std::current_exception() может вернуть bad_exception, если не удалось создать копию текущего исключения (если таковая понадобилась).

Ну, я стандарты С++ не считаю откровением господним. Интересно не то, чего они не гарантируют, а то, что вообще можно получить — хотя бы в теории.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Какие у исключений проблемы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.11.14 09:07
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>А можно через монады организовать, например, циклы? Чисто гипотетически, конечно, но все равно: сперва "открыть", потом произвольное количество раз сначала "читать", потом "писать", и в самом конце "закрыть".

Ну, такое-то можно и без монад.
Достаточно сильная система типов отличает "новый сокет" от "открытого сокета" и от "закрытого сокета". Поэтому достаточно объявить правильные сигнатуры у функций открытия/чтения/закрытия.

ARK>Ну да, этого недостаточно. Я, кстати, не могу придумать нормального варианта, как быть в такой ситуации, то бишь если происходит крах при финализации. Похоже, единственное, что можно сделать — как-то передать ошибку наверх. Но при этом должны выполниться и все остальные деструкторы. Правда, ошибка в первом деструкторе может повлиять и на остальные... В общем, хз, как лучше. Конечно, лучше всего статически запретить любые ошибки в финализаторах, но это не сработает для внешних сущностей — баз данных, сетевых соединений и т.п.

Надо понять,
1. Что мы хотим делать в случае возникновения ошибки на таком этапе. Если вообще отвлечься от деструкторов, финализаторов, скоупов, и исключений. Вот мы писали-писали данные в буфер, вот стали сохранять — облом, кончилось место на диске. Что мы будем делать? Пытаться повторно? Откатывать назад к "предыдущему успешному чекпоинту"?
2. Отличается ли стратегия завершения для успеха и неудачи. Предположим, в процессе подготовки данных для записи в файл мы напоролись на деление на ноль. Имеет ли смысл вообще пытаться записывать кусок буфера? Или надо откатываться к "предыдущему успешному чекпоинту"? Или можно просто бросить как есть, т.к. упорно пытаться записывать мусор бессмысленно, а откатывать назад — дорого.

Пока что выглядит всё так, что даже пытаться делать commit стоит только при условии выхода из блока без исключений. При исключительном выходе нужно применять либо rollback, либо ignore.

Дальше начинаются нюансы — что, если у нас три файла, выходим успешно, один уже закоммитился, теперь коммитим второй — упс, ошибка. Очевидное решение (скорее всего неверное) — продолжать отмотку с учётом изменившейся ситуации. То есть для второго и третьего мы попробуем теперь вызвать "завершатель ошибки".

В таком подходе можно попытаться запретить (языком и верификацией) выброс исключений из fault completion handler, разрешая нетривиальную логику в success completion handler.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: Какие у исключений проблемы?
От: jazzer Россия Skype: enerjazzer
Дата: 12.11.14 09:22
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


J>>А чего ты тогда хочешь? Что входит в твое понятие антонима? Просто попытка вызвать обратное действие, независимо от того, будет она успешной или нет?

S>Антоним — это то действие, которое я заложил в алгоритм.
S>Вот, например, банальная штука на воображаемом языке:
S>
S>using(var stream = openSerializationStream())
S>{
S>  stream.Write("Customer", customer);
S>  if (customer.Status < Status.Ready)
S>    return; // #1 - no data saved for the not ready customers

S>  var orders = Orders.GetOrders(customer) ;
 
S>  if (orders.Length==0)
S>    return; #2 - nothing to save
S>  stream.Write("OrdersTotal", orders.Total(o=>o.Amount));
S>  foreach(var o in orders)
S>    if (o.Status != Status.Ready)
S>       break; # 3 - list all ready orders, then exit
S>    else
S>       stream.Write("Order #"+o.Id, o);
S>}
S>

S>Я хочу двух вещей:
S>1. Чтобы у меня буфер сбрасывался на диск не после каждой операции, но при выходе из scope. То есть я не хочу ни добавлять принудительный flush к Write (страдает перформанс), ни руками дописывать stream.Flush() перед каждым return/break/} (чревато ошибками).
S>2. Чтобы о об ошибках записи я узнавал не из чтения побитого файла, а из вылетающего исключения.

Что ты собираешься получить, если и одна из операций сломалась, и автоматический Flush?

S>В С++ сие невозможно, т.к. единственное, что гарантированно сработает при выходе — это деструктор, а в деструкторе бросать исключения нельзя.

Если очень хочется — то можно.

J>>Скажем, один, восстанавливает курсор, а второй гасит лампочку на девайсе, подключенном по COM-порту.

S>Это — вопрос, требующий проработки. У меня нет всех деталей задачи про курсор и лампочку; потому мне сложно сказать, какие гарантии тут нужны. Потому что по ком-порту может быть не лампочка подключена, а электронный замок, перекрывающий дверь шлюза. И подавление исключения означает "да хрен с ним, с этим шлюзом — нехай экипаж задохнётся".

А зачем тогда делать важные вещи невидимой автоматикой без внятной обработки ошибок, которые могут в этих важных вещах возникнуть?
И что бы ты делал без исключений, если у тебя возникло несколько ошибок сразу?

Суть кода с исключениями — прервать цепочку действий, почиститься и передать это исключение наверх. Именно это, а не то, которое возникнет в результате очистки. Ну или по крайней мере оно не должно быть главным, а быть упрятанным в какой-нть nested и проигнорированным в цепочке действий по очистке, чтоб остальные тоже могли почиститься. Хотя там могут быть свои взаимозависимости, так что все это — прогулки по граблям, вне зависимости от наличия или отсутствия исключений.

J>>Плюс возврат ошибки в случае отвалившегося антонима — это очень сомнительная практика сама по себе.

J>>Типа ты вызываешь функцию для долгого расчета интеграла, а в ответ получаешь ошибку "не смогли восстановить курсор-стрелочку".
S>Это потому, что вам не жалко курсор. А что, если функция для долгого расчёта не смогла результат в файл сохранить. Вы тоже сочтёте сомнительной практику как-то намекнуть об этом вызывающему коду?

Я сочту сомнительной практикой засовывать сохранение результатов в деструктор, вместо того, чтобы сделать это отдельной явной строчкой. Это ведь можно до абсурда дойти — не писать функций вообще, весь код в деструкторах, а в функциях только создание объектов и тут же их автоматическое уничтожение.


J>>Ну еще есть scope(exit), scope(success), scope(failure) — ты их имеешь в виду?

S>А что это? Может и их.
Это способ задать действия в деструкторе в зависимости от того, в каких условиях вызвался деструктор — по-нормальному (success), в результате раскрутки стека из-за исключения (failure), пофиг что (exit).
Встроено в D, есть реализация для С++:
http://rsdn.ru/forum/cpp/4908728.1
Автор: Evgeny.Panasyuk
Дата: 27.09.12


В случае success исключение можно бросить, в принципе.

J>>По Стандарту С++11 — никаких гарантий, увы, нет. Даже std::current_exception() может вернуть bad_exception, если не удалось создать копию текущего исключения (если таковая понадобилась).

S>Ну, я стандарты С++ не считаю откровением господним. Интересно не то, чего они не гарантируют, а то, что вообще можно получить — хотя бы в теории.

В теории это всё криво. Я не видел ни одной схемы вменяемой автоматизированной обработки ошибок обработки ошибок обработки ошибок.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[21]: Какие у исключений проблемы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.11.14 10:15
Оценка: +1
Здравствуйте, jazzer, Вы писали:

J>Что ты собираешься получить, если и одна из операций сломалась, и автоматический Flush?

Ну, например в данном случае, если одна из операций сломалась, то я не хочу автоматический Flush().
J>Если очень хочется — то можно.
И такое исключение поймают?

J>А зачем тогда делать важные вещи невидимой автоматикой без внятной обработки ошибок, которые могут в этих важных вещах возникнуть?

Затем, чтобы минимизировать шансы на ошибку. Потому что "класс шлюза" проектирует один человек, а применяет — совсем другой.
И этот другой может вообще быть не в курсе, что добавленный им return открывает дыру с последствиями типа Чернобыля.

J>И что бы ты делал без исключений, если у тебя возникло несколько ошибок сразу?

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

J>Суть кода с исключениями — прервать цепочку действий, почиститься и передать это исключение наверх.

Да-да, весь вопрос только в том, что означает "почиститься".

J>Именно это, а не то, которое возникнет в результате очистки. Ну или по крайней мере оно не должно быть главным, а быть упрятанным в какой-нть nested и проигнорированным в цепочке действий по очистке, чтоб остальные тоже могли почиститься. Хотя там могут быть свои взаимозависимости, так что все это — прогулки по граблям, вне зависимости от наличия или отсутствия исключений.

Ну да. Вообще всё программирование — это прогулки по граблям. Вы не знали? Весь прогресс связан только с тем, чтобы сократить количество этих граблей.
Введя, например, принудительную type safety.

J>Я сочту сомнительной практикой засовывать сохранение результатов в деструктор, вместо того, чтобы сделать это отдельной явной строчкой.

Я тоже. Но ведь кроме деструкторов у нас (в С++) ничего нету. А идея "сделать это отдельной явной строчкой" — регрессивна.
Зачем тогда нам деструкторы? Ведь нетрудно же "почиститься" отдельной явной строчкой при выходе из каждого scope. Тем более, что непустые деструкторы вообще редко нужны.


J>Это ведь можно до абсурда дойти — не писать функций вообще, весь код в деструкторах, а в функциях только создание объектов и тут же их автоматическое уничтожение.

Можно и в обратную сторону до абсурда дойти. Вот только зачем?

J>Встроено в D, есть реализация для С++:

J>http://rsdn.ru/forum/cpp/4908728.1
Автор: Evgeny.Panasyuk
Дата: 27.09.12

Прикольно! Вот об этом я и говорил.
J>В случае success исключение можно бросить, в принципе.
Вот, одна из возможных реализаций.

J>В теории это всё криво. Я не видел ни одной схемы вменяемой автоматизированной обработки ошибок обработки ошибок обработки ошибок.

Поэтому надо дать возможность работать с ними вручную. Напомню: исключения — тоже "неавтоматизированы". catch за вас никто не напишет. Зато дают возможность вам выразить свои намерения компактно и корректно.
Хочется ещё компактнее и корректнее.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: Какие у исключений проблемы?
От: enji  
Дата: 12.11.14 12:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

E>>Да вмещается он, просто надо вместо целого кода возвращать объект. А там уже можно делать вложенные коды и т.п. Но от ручного распространения без какого-то сахара со стороны языка не уйти, да

S>Стесняюсь спросить — а в чём преимущество-то у этого "объекта ошибки" по сравнению с "объектом-исключением"?

это ты не у меня спрашивай. Тут выше рассказывали, что коды ошибок более очевидны... Лично я использую исключения
Re[16]: Какие у исключений проблемы?
От: enji  
Дата: 12.11.14 12:40
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Может быть, два "деструктора" у классов — commit-деструктор и rollback-деструктор?

вот это кстати вполне в духе плюсов, странно что еще не сделали

S>Или другую семантику раскрутки стека, которая позволяет спасти больше информации об ошибке? Типа "мы читали из одного файла и писали в другой, потом при чтении у нас возникла ошибка формата, а при экстренном выходе мы и предыдущие данные в выходной файл записать не смогли".


Дык одно из исключений добавлять к основному. Проблема в плюсах в том, что можно выкинуть любой объект (очень интересно, зачем?).
Re[17]: Какие у исключений проблемы?
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.11.14 12:47
Оценка:
Здравствуйте, enji, Вы писали:

E>Дык одно из исключений добавлять к основному. Проблема в плюсах в том, что можно выкинуть любой объект (очень интересно, зачем?).

Зачем как раз понятно — чтобы можно было "не платить за то, чего не используешь" — в случае чего прямо throw hr; catch(HRESULT).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: Какие у исключений проблемы?
От: enji  
Дата: 12.11.14 12:56
Оценка:
Здравствуйте, Sinclair, Вы писали:

J>>Что ты собираешься получить, если и одна из операций сломалась, и автоматический Flush?

S>Ну, например в данном случае, если одна из операций сломалась, то я не хочу автоматический Flush().

к примеру в плюсах есть std::uncaught_exception.
Re[22]: Какие у исключений проблемы?
От: AlexRK  
Дата: 12.11.14 14:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Пока что выглядит всё так, что даже пытаться делать commit стоит только при условии выхода из блока без исключений. При исключительном выходе нужно применять либо rollback, либо ignore.

S>Дальше начинаются нюансы — что, если у нас три файла, выходим успешно, один уже закоммитился, теперь коммитим второй — упс, ошибка. Очевидное решение (скорее всего неверное) — продолжать отмотку с учётом изменившейся ситуации. То есть для второго и третьего мы попробуем теперь вызвать "завершатель ошибки".
S>В таком подходе можно попытаться запретить (языком и верификацией) выброс исключений из fault completion handler, разрешая нетривиальную логику в success completion handler.

Да блин, мне _вообще_ непонятно, какова должна быть грамотная стратегия обработки ошибок при финализации.
Если у нас есть блок, внутри которого содержатся 10 автоматических переменных, то что должно произойти при выходе из блока, если при вызове первого деструктора вылетела ошибка?
Если бы был полный STM с учетом IO, то все было бы супер. Но его нету. Что делать? Выполнять остальные деструкторы или нет? Все ошибки из всех деструкторов склеить в одно исключение и кидануть его наверх?
Re[17]: Какие у исключений проблемы?
От: alex_public  
Дата: 12.11.14 18:12
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Да, я в курсе, и проектируешь все проекты на сто лет вперёд, учитывая все возможные и невозможные изменения требований, а так же учитываешь все случаи реюзания твоего кода всеми возможными и невозможными способами.


Дело не в устройстве приложения, а в самой прикладной задаче.

Вот смотри, у тебя задача скачать файл из сети по данному url'у. Понятно что по такой вроде бы просто формулируемой задаче мы имеем наверное больше десятка низкоуровневых ошибок (начиная с открытия сокета и заканчивая записью на диск). Теперь простой вопрос: что ты планируешь выдавать пользователю в данном случае? )
Re[23]: Какие у исключений проблемы?
От: AlexRK  
Дата: 14.11.14 07:19
Оценка: -1
Здравствуйте, AlexRK, Вы писали:

ARK>Да блин, мне _вообще_ непонятно, какова должна быть грамотная стратегия обработки ошибок при финализации.

ARK>Если у нас есть блок, внутри которого содержатся 10 автоматических переменных, то что должно произойти при выходе из блока, если при вызове первого деструктора вылетела ошибка?
ARK>Если бы был полный STM с учетом IO, то все было бы супер. Но его нету. Что делать? Выполнять остальные деструкторы или нет? Все ошибки из всех деструкторов склеить в одно исключение и кидануть его наверх?

Прочитал http://rsdn.ru/forum/cpp/4908728.all
Автор: Evgeny.Panasyuk
Дата: 27.09.12
, подумал.

Пока что все выглядит так, что я открываю Америку — деструкторы не должны возвращать ошибку, а все действия, которые могут ее вернуть, должны быть вызваны явно. По сути мы просто перекладываем всю логику обработки на программиста.

Но в этом свете хваленый RAII оказывается просто пшиком, потому что безошибочно с гарантией освободить можно только память.
Не, можно конечно просто плюнуть на полную корректность, как в С++ и поступают. "Подумаешь, файл не закрылся, этого почти никогда и не бывает."
Но для меня такой вариант неприемлем.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.