Re[6]: Какие у исключений проблемы?
От: dimgel Россия https://github.com/dimgel
Дата: 06.11.14 21:45
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>в некоторых новых языках решили отказаться от искючений


Кому как, а мне такие языки не нужны.
Re[2]: Какие у исключений проблемы?
От: Философ Ад http://vk.com/id10256428
Дата: 06.11.14 22:08
Оценка: :)
Здравствуйте, Pzz, Вы писали:

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


Если ты не знаешь что делать с ошибкой, прибивай программу. Это намного лучше чем считать погоду в Африке.
Низкоуровневое исключение — это почти всегда открытые открытые файлы, захваченные мьютексы/критические секции, выделенная память и т.д, но самое главное — инконсистентное состояние программы.
Всё сказанное выше — личное мнение, если не указано обратное.
Re: Какие у исключений проблемы?
От: alex_public  
Дата: 06.11.14 23:26
Оценка: +2 :)))
Здравствуйте, vsb, Вы писали:

Когда-то этот вопрос уже здесь обсуждался, причём именно для случая C++ (в контексте запрета исключений в гугловских руководствах). Я тогда подробно (с подтверждающими примерами) изложил свою точку зрения. Могу повторить тезисно в этой темке.

Главное преимущество исключений в том, что они позволяют без напряжения для программиста и оптимально по быстродействию (как раз тесты из данной темки это подтверждают) передавать ошибку через множество уровней стека вызова. Так вот, на мой взгляд на практике нормальная обработка ошибок всегда происходит практически на следующем уровне вложенности, а не где-то далеко наверху. Происходит это по уже упоминаемой тут причине — иначе не получится выдавать адекватные сообщения об ошибках. Т.е. даже если мы сделаем идеальный для системы исключений случай с единственной на всю программу точкой реакции на ошибки (грубо говоря один try/catch на всю программу), то нам всё равно придётся по несколько раз переупаковывать их по ходу дела (хотя бы потому, что одинаковые низкоуровневые исключения в разных модулях означают разные вещи). Т.е. в итоге мы всё равно приходим к кучей блоков try/catch раскиданных по всей программе, причём как показывает практика, чаще всего они будут прямо вокруг функции кидающей исключение. А это полностью убирает все преимущества исключений. Более того, при таком раскладе они становятся более многословным и при этом менее явным способом работы.
Re[10]: Какие у исключений проблемы?
От: jazzer Россия Skype: enerjazzer
Дата: 07.11.14 02:04
Оценка: 4 (1) +1
Здравствуйте, Vain, Вы писали:

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


V>>>непонятно только, как исключения в этом случае будут быстрее кодов ошибок?

U>>Коды ошибок всегда проверять нужно, произошла ошибка или нет. А исключения задействуются, только когда произошла ошибка.
V>Ну это не совсем так, при входе в try блок ведь чтото должно делаться, не так ли? Единственный вопрос, быстрее ли оно обычного условия в случае проверки кода возврата.

Нет, ничего не надо делать, это обычный scope с толпой деструкторов в конце. И исключение — это по сути табличное goto куда-то в середину этой пачки деструкторов, в зависимости от того, в какой строчке вылетело исключение (чтоб убить только то, что успело создаться к этому моменту). И место goto вычисляется только при размотке стека в случае исключения.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Отредактировано 07.11.2014 6:52 jazzer . Предыдущая версия .
Re[2]: Какие у исключений проблемы?
От: AlexRK  
Дата: 07.11.14 06:41
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Т.е. в итоге мы всё равно приходим к кучей блоков try/catch раскиданных по всей программе, причём как показывает практика, чаще всего они будут прямо вокруг функции кидающей исключение. А это полностью убирает все преимущества исключений. Более того, при таком раскладе они становятся более многословным и при этом менее явным способом работы.


+1

Во всех мало-мальски крупных системах, которые я видел (не миллионы строк, но сотни тысяч) — именно так и есть. Причем я говорю о софте разного типа (записи судебных заседаний, ГИС, программы учета), созданном в разных компаниях (в т.ч. занимающихся исключительно разработкой ПО).
Re[9]: Какие у исключений проблемы?
От: Miroff Россия  
Дата: 07.11.14 06:51
Оценка:
Здравствуйте, enji, Вы писали:

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


M>>Запретить null как класс. Вместо него использовать либо Option, либо вообще ничего не использовать.


E>И кстати — как его запретить? Вообще запретить простые ссылки? Т.е. везде только Option?


Запретить неинициализированные ссылки и ключевое слово null.

Т.е.

User user; // error

return null; // error

foo(null); //error


E>И во что тогда превратится такое: obj1.calc().doIt().getSome() ?


За такой код в приличном обществе принято бить канделябром потому что это нарушение DSP.
Re[2]: Какие у исключений проблемы?
От: jazzer Россия Skype: enerjazzer
Дата: 07.11.14 06:57
Оценка:
Здравствуйте, alex_public, Вы писали:

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


_>Когда-то этот вопрос уже здесь обсуждался, причём именно для случая C++ (в контексте запрета исключений в гугловских руководствах). Я тогда подробно (с подтверждающими примерами) изложил свою точку зрения. Могу повторить тезисно в этой темке.


_>Главное преимущество исключений в том, что они позволяют без напряжения для программиста и оптимально по быстродействию (как раз тесты из данной темки это подтверждают) передавать ошибку через множество уровней стека вызова. Так вот, на мой взгляд на практике нормальная обработка ошибок всегда происходит практически на следующем уровне вложенности, а не где-то далеко наверху. Происходит это по уже упоминаемой тут причине — иначе не получится выдавать адекватные сообщения об ошибках. Т.е. даже если мы сделаем идеальный для системы исключений случай с единственной на всю программу точкой реакции на ошибки (грубо говоря один try/catch на всю программу), то нам всё равно придётся по несколько раз переупаковывать их по ходу дела (хотя бы потому, что одинаковые низкоуровневые исключения в разных модулях означают разные вещи). Т.е. в итоге мы всё равно приходим к кучей блоков try/catch раскиданных по всей программе, причём как показывает практика, чаще всего они будут прямо вокруг функции кидающей исключение. А это полностью убирает все преимущества исключений. Более того, при таком раскладе они становятся более многословным и при этом менее явным способом работы.


Все эти промежуточные try/catch не добавляют ничего, если исключение не было брошено.
Суть в том, чтоб оптимизировать сценарий, когда исключения не летят.
А если летят — то пофиг, насколько медленно это делается, что там как переупаковывается и т.д.
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[10]: Какие у исключений проблемы?
От: dimgel Россия https://github.com/dimgel
Дата: 07.11.14 07:48
Оценка:
Здравствуйте, Miroff, Вы писали:

E>>И во что тогда превратится такое: obj1.calc().doIt().getSome() ?


M>За такой код в приличном обществе принято бить канделябром потому что это нарушение DSP.


Напомни плиз, как это DSP расшифровывается. А то идею помню (что-то там типа не более двух ссылок в цепочке, иначе заворачивать в методы) и юзаю давно на автомате, а нагуглить не могу.
Re[11]: Какие у исключений проблемы?
От: AlexRK  
Дата: 07.11.14 07:53
Оценка: 8 (1)
Здравствуйте, dimgel, Вы писали:

D>Напомни плиз, как это DSP расшифровывается. А то идею помню (что-то там типа не более двух ссылок в цепочке, иначе заворачивать в методы) и юзаю давно на автомате, а нагуглить не могу.


Закон Деметры.
http://en.wikipedia.org/wiki/Law_of_Demeter
Re[12]: Какие у исключений проблемы?
От: dimgel Россия https://github.com/dimgel
Дата: 07.11.14 08:03
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Закон Деметры.

ARK>http://en.wikipedia.org/wiki/Law_of_Demeter

Во, точно, спасибо. Ещё ж хихикал в своё время от ассоциации с поттеровскими дементорами.
Re[11]: Какие у исключений проблемы?
От: Vain Россия google.ru
Дата: 07.11.14 08:09
Оценка:
Здравствуйте, jazzer, Вы писали:

V>>Ну это не совсем так, при входе в try блок ведь чтото должно делаться, не так ли? Единственный вопрос, быстрее ли оно обычного условия в случае проверки кода возврата.

J>Нет, ничего не надо делать, это обычный scope с толпой деструкторов в конце.
ну значит расходы на вход в скоп:
#include <stdio.h>
#include <stdlib.h>

struct A {};

int main()
{
00E61002  in          al,dx  
00E61003  push        0FFFFFFFFh  
00E61005  push        offset __ehhandler$_main (0E61980h)  
00E6100A  mov         eax,dword ptr fs:[00000000h]  
00E61010  push        eax  
00E61011  mov         dword ptr fs:[0],esp  
00E61018  sub         esp,8  
00E6101B  push        ebx  
00E6101C  push        esi  
00E6101D  push        edi  
00E6101E  mov         dword ptr [ebp-10h],esp  
    int i = 123;
    try {
00E61021  mov         dword ptr [ebp-4],0
        if(!rand()) {
00E61028  call        dword ptr [__imp__rand (0E620A4h)]  
00E6102E  test        eax,eax  
00E61030  jne         $LN8 (0E6104Bh)  
            throw A();
00E61032  xor         al,al  
00E61034  mov         byte ptr [ebp-11h],al  
00E61037  push        offset __TI1?AUA@@ (0E622C8h)  
00E6103C  lea         eax,[ebp-11h]  
00E6103F  push        eax  
00E61040  call        _CxxThrowException (0E61970h)  
        }
    }
    catch(...) {
    }
00E61045  mov         eax,offset $LN8 (0E6104Bh)  
00E6104A  ret  
    printf("%i\n", i);
00E6104B  push        7Bh  
00E6104D  push        offset string "%i\n" (0E6210Ch)  
00E61052  call        dword ptr [__imp__printf (0E620ACh)]  

    return 0;
}
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: Какие у исключений проблемы?
От: alex_public  
Дата: 07.11.14 08:20
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Все эти промежуточные try/catch не добавляют ничего, если исключение не было брошено.

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

Ну вообще говоря это зависит от реализации, sjlj/seh/dwarf и т.п. Но в данном случае я говорил не об оптимизации, а об удобстве программиста. Ведь если ловить исключения непосредственно над функцией кидающей их, это получается заметно более громоздко и неудобно. Т.е. сама теоретическая идея исключений очень хороша, но на практике весьма редко получается использовать её преимущества (более того, при указанном выше раскладе, она скорее во вред уже идёт).
Re[11]: Какие у исключений проблемы?
От: Miroff Россия  
Дата: 07.11.14 08:21
Оценка: 8 (1)
Здравствуйте, dimgel, Вы писали:

D>Напомни плиз, как это DSP расшифровывается. А то идею помню (что-то там типа не более двух ссылок в цепочке, иначе заворачивать в методы) и юзаю давно на автомате, а нагуглить не могу.


Извиняюсь, LoD конечно.

https://en.wikipedia.org/wiki/Law_of_Demeter
Re[12]: Какие у исключений проблемы?
От: dimgel Россия https://github.com/dimgel
Дата: 07.11.14 08:25
Оценка:
Здравствуйте, Miroff, Вы писали:

M>https://en.wikipedia.org/wiki/Law_of_Demeter


(зевает) Я, оказывается, и идею не помнил: не лезть через голову контрагента, а длина цепочки — уже следствие. Хотя юзал на автопилоте всё равно правильно, в подсознание вбил однако.
Отредактировано 07.11.2014 8:27 dimgel . Предыдущая версия .
Re[12]: Какие у исключений проблемы?
От: AlexRK  
Дата: 07.11.14 08:26
Оценка: :)
Здравствуйте, Miroff, Вы писали:

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


D>>Напомни плиз, как это DSP расшифровывается. А то идею помню (что-то там типа не более двух ссылок в цепочке, иначе заворачивать в методы) и юзаю давно на автомате, а нагуглить не могу.


M> Извиняюсь, LoD конечно.


Demeter's Substitution Principle.
Re[4]: Какие у исключений проблемы?
От: jazzer Россия Skype: enerjazzer
Дата: 07.11.14 10:01
Оценка: 6 (1) +4
Здравствуйте, alex_public, Вы писали:

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


J>>Все эти промежуточные try/catch не добавляют ничего, если исключение не было брошено.

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

_>Ну вообще говоря это зависит от реализации, sjlj/seh/dwarf и т.п. Но в данном случае я говорил не об оптимизации, а об удобстве программиста. Ведь если ловить исключения непосредственно над функцией кидающей их, это получается заметно более громоздко и неудобно.


А можно продемонстрировать громоздкость и неудобность на примере?
Вот чтобы передавалась наверх одна и та же информация, только один раз — кодом возврата, а другой раз — исключением.
Ну чтоб было видно, что исключения сливают, на примере, так сказать.

Скажем, нужно открыть 4 сокета, прочитав параметры из разных конфигов. Мы делаем вперемежку 4 вызова функции (или конструктора обертки) open_file, которая может бросить исключение EFileOpen(filename,errno), и 4 вызова функции open_socket, которая может бросить исключение ESocketOpen(sourceIP,sourcePort,targetIP,targetPort,errno).
И вылетевшее исключение переупаковываются в, скажем, EEnvSetup(username).

Как ты понимаешь, c исключениями и переупаковкой код будет примерно таким:
try {
  auto f1 = open_file(get_profile_dir(username)+"file1");
  s1_ = open_socket(f1); // читаем из конфига
  auto f2 = open_file(get_profile_dir(username)+"file2");
  s2_ = open_socket(f2); // читаем из конфига
  auto f3 = open_file(get_profile_dir(username)+"file3");
  s3_ = open_socket(f3); // читаем из конфига
  auto f4 = open_file(get_profile_dir(username)+"file4");
  s4_ = open_socket(f4); // читаем из конфига
}
catch(...) {
  std::throw_with_nested( EEnvSetup(username) );
}


_>Т.е. сама теоретическая идея исключений очень хороша, но на практике весьма редко получается использовать её преимущества (более того, при указанном выше раскладе, она скорее во вред уже идёт).


Ну, моя практика от твоей отличается, видимо.
Я вижу сплошные удобства в своем коде, и каждый вызов каждой функции в отдельный try/catch не заворачиваю.
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[5]: Какие у исключений проблемы?
От: alex_public  
Дата: 07.11.14 10:55
Оценка:
Здравствуйте, jazzer, Вы писали:

J>А можно продемонстрировать громоздкость и неудобность на примере?

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

Обсуждалось это всё уже давным давно) Причём и вместо с тобой. ))) Например здесь http://rsdn.ru/forum/cpp/4623107?tree=tree
Автор: alex_public
Дата: 18.02.12
(и там дальше по ветке основное будет) можно глянуть.

J>Скажем, нужно открыть 4 сокета, прочитав параметры из разных конфигов. Мы делаем вперемежку 4 вызова функции (или конструктора обертки) open_file, которая может бросить исключение EFileOpen(filename,errno), и 4 вызова функции open_socket, которая может бросить исключение ESocketOpen(sourceIP,sourcePort,targetIP,targetPort,errno).

J>И вылетевшее исключение переупаковываются в, скажем, EEnvSetup(username).

Я же говорю, проблемы у исключений не в теории, а на практике. Конкретно на практике мне не приходилось писать код с последовательным открытием 4-х сокетов (причём так что проблемы с одним отменяют попытки с остальными) в одной функции. Но зато вполне частенько встречался код вида
auto f1 = open_file(get_profile(username));
if(!f1) f1=open_file(get_default_profile());
s1_ = open_socket(f1); // читаем из конфига

Понимаешь что получится, в случае переписывания такого варианта твоего кода на исключениях? )

J>Ну, моя практика от твоей отличается, видимо.

J>Я вижу сплошные удобства в своем коде, и каждый вызов каждой функции в отдельный try/catch не заворачиваю.

Я говорил не про оборачивание каждого вызова, а про перехват исключений на следующем уровне (а не где-то высоко). Что ты как раз и продемонстрировал в своём примере. Но и оборачивание отдельных функций тоже возможно, если требуется продолжить нормальное исполнение программы после неудачного вызова функции.
Re[2]: Какие у исключений проблемы?
От: slava_phirsov Россия  
Дата: 07.11.14 11:04
Оценка: +2 :)
Здравствуйте, LaptevVV, Вы писали:

LVV>Одна из серьезных проблем, которую практически не поминают — это парадигма обработки исключений.

LVV>И вот получается, что в одной проге смешаны как минимум две, а то и три парадигмы: ООП+событийное (и очень часто процедурное).

О! Ребята начали чего-то подозревать! Я, помнится, спрашивал тут когда-то: "а как вы собираетесь реагировать на исключения, где перехватывать (если собираетесь перехватывать)". Исключальщики меня только об[какали], типа, у нас все тип-топ, транзакционная семантика, и вообще ты не в теме, учи матчасть.

LVV>И если нормальную работу худо-бедно проектируют, то аварии не проектируют совсем.

Да ладно не проектируют, их и не тестируют совсем — вот беда! За исключением (пардон за каламбур) тривиальных случаев: неправильный аргумент -> функция кидает исключение. И я даже с трудом себе представляю, а как можно написать юнит-тесты для кода, обрабатывающего аварии.

LVV>Надо отметить, что в новом стандарте управляемость исключений СУЩЕСТВЕННО улучшилась.

LVV>Текущее исключение можно явным образом сохранить, передать в нужную функцию, заново кинуть в нужном месте.

Но вот спецификации исключений, вместо того, чтобы довести до ума (== до уровня Java) предпочли выпилить, чтобы не париться Уж тут либо полноценные исключения со спецификациями и (может быть) с ограничением распространения по стеку вызовов, по области видимости (например, исключение является внутренним для данного класса), либо ну их нафиг.

Нет, когда Страуструп в D&E написал, что исключения в C++ — это первый опыт комитетской разработки, я не удивился ничуть. "Верблюд — это скаковая лошадь, спроектированная комитетом по стандартизации"(c)
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[6]: Какие у исключений проблемы?
От: jazzer Россия Skype: enerjazzer
Дата: 07.11.14 13:48
Оценка: +1
Здравствуйте, alex_public, Вы писали:

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


J>>А можно продемонстрировать громоздкость и неудобность на примере?

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

_>Обсуждалось это всё уже давным давно) Причём и вместо с тобой. ))) Например здесь http://rsdn.ru/forum/cpp/4623107?tree=tree
Автор: alex_public
Дата: 18.02.12
(и там дальше по ветке основное будет) можно глянуть.


Ну глянул. Моя позиция не изменилась. Ты там, вроде, мне не возражал.

J>>Скажем, нужно открыть 4 сокета, прочитав параметры из разных конфигов. Мы делаем вперемежку 4 вызова функции (или конструктора обертки) open_file, которая может бросить исключение EFileOpen(filename,errno), и 4 вызова функции open_socket, которая может бросить исключение ESocketOpen(sourceIP,sourcePort,targetIP,targetPort,errno).

J>>И вылетевшее исключение переупаковываются в, скажем, EEnvSetup(username).

_>Я же говорю, проблемы у исключений не в теории, а на практике. Конкретно на практике мне не приходилось писать код с последовательным открытием 4-х сокетов (причём так что проблемы с одним отменяют попытки с остальными) в одной функции.

А мне вот приходится регулярно. Там сокеты, правда, упрятаны внутрь соответствующих транспортов/протоколов, но это роли не играет — они все создаются разом и все должны работать.

_>Но зато вполне частенько встречался код вида

_>
_>auto f1 = open_file(get_profile(username));
_>if(!f1) f1=open_file(get_default_profile());
_>s1_ = open_socket(f1); // читаем из конфига
_>

_>Понимаешь что получится, в случае переписывания такого варианта твоего кода на исключениях? )

Во-первых, в таких случаях используются функции типа can_open_file(filename), но даже в твоей формулировке:
try {
  try {
    f1 = open_file(get_profile(username));
  } catch (...) {
    f1 = open_file(get_default_profile());
  }
  s1_ = open_socket(f1); // читаем из конфига
}
catch(...) { std::throw_with_nested( EEnvSetup(username) ); }

а в реальном коде, даже если у нас в API только исключения, будет отдельная функция
auto get_profile_or_default(string username)
{
  try {
    return open_file(get_profile(username));
  } catch(...) {
    return open_file(get_default_profile());
  }
}

и далее в коде все, как раньше:
try {
  f1  = get_profile_or_default(username);
  s1_ = open_socket(f1); // читаем из конфига
}
catch(...) { std::throw_with_nested( EEnvSetup(username) ); }


Ну а теперь изобрази свой замечательный вариант на кодах возврата. С донесением всей необходимой информации на верхний уровень: если не открылся файл, то какой и почему, если сокет, то какой и почему.
Жду-пожду.

J>>Ну, моя практика от твоей отличается, видимо.

J>>Я вижу сплошные удобства в своем коде, и каждый вызов каждой функции в отдельный try/catch не заворачиваю.

_>Я говорил не про оборачивание каждого вызова, а про перехват исключений на следующем уровне (а не где-то высоко). Что ты как раз и продемонстрировал в своём примере.


Да, продемонстрировал. И как, это было так ужасно, что ты демонстрацию стер с глаз долой? Целая одна строчка с std::throw_with_nested?

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

Да, на верхнем уровне, скажем, в обработчике кнопок меню: прилетело исключение — рассказал пользователю, что облом (с показом по требованию всей собранной исключениями через throw_with_nested информации), и работаешь себе дальше.
Потому что если можно продолжить нормальное исполнение программы после неудачного вызова функции на низком уровне, то это не исключительная ситуация по определению, правда?
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[7]: Какие у исключений проблемы?
От: alex_public  
Дата: 07.11.14 15:21
Оценка:
Здравствуйте, jazzer, Вы писали:

_>>Обсуждалось это всё уже давным давно) Причём и вместо с тобой. ))) Например здесь http://rsdn.ru/forum/cpp/4623107?tree=tree
Автор: alex_public
Дата: 18.02.12
(и там дальше по ветке основное будет) можно глянуть.

J>Ну глянул. Моя позиция не изменилась. Ты там, вроде, мне не возражал.

Ну так консенсус (во всяком случае у меня с собеседникам) там сложился на формулировке "исключения хорошо подходят для обработки критических (т.е. после которых программа скорее всего прервёт исполнение) ошибок, а не всех видов ошибок вообще". Причём тут есть ещё хитрый нюанс — ошибки во многих API (типа того же открытия файла) могут быть как критическими, так и нет, в зависимости от контекста использования. Получается что по идее надо бы иметь по два вида API в таких библиотеках. Но Boost.Asio — это скорее исключение, чем правило...

В общем для большинства случаев (если не трогать таки вещи как скажем new) мне кажется, что лучше делать интерфейс без исключений. Ну или тогда уж оба варианта, как в Asio.

J>Во-первых, в таких случаях используются функции типа can_open_file(filename), но даже в твоей формулировке:

J>
J>try {
J>  try {
J>    f1 = open_file(get_profile(username));
J>  } catch (...) {
J>    f1 = open_file(get_default_profile());
J>  }
J>  s1_ = open_socket(f1); // читаем из конфига
J>}
J>catch(...) { std::throw_with_nested( EEnvSetup(username) ); }
J>

J>а в реальном коде, даже если у нас в API только исключения, будет отдельная функция
J>
J>auto get_profile_or_default(string username)
J>{
J>  try {
J>    return open_file(get_profile(username));
J>  } catch(...) {
J>    return open_file(get_default_profile());
J>  }
J>}
J>

J>и далее в коде все, как раньше:
J>
J>try {
J>  f1  = get_profile_or_default(username);
J>  s1_ = open_socket(f1); // читаем из конфига
J>}
J>catch(...) { std::throw_with_nested( EEnvSetup(username) ); }
J>


Ну так разве это всё не ужас, по сравнению с тем моим кодом в 3 строчки? )

J>Ну а теперь изобрази свой замечательный вариант на кодах возврата. С донесением всей необходимой информации на верхний уровень: если не открылся файл, то какой и почему, если сокет, то какой и почему.

J>Жду-пожду.

Так а зачем выносить эту информацию на верхний уровень? ) Пользователю будешь это показывать? ))) Как раз это и обсуждалось в той старой темке...

J>Да, продемонстрировал. И как, это было так ужасно, что ты демонстрацию стер с глаз долой? Целая одна строчка с std::throw_with_nested?


Не о том речь. Просто у исключений есть очевидные преимущества. Но они проявляются как раз для случая проброса через длинный стек вызова. Т.е. в идеальной модели с исключениями мы имеет вообще один единственный блок с try/catch на всю программу. Так вот, я как раз и утверждаю, что на практике такая модель может получиться только в очень специфических случаях. И ты только подтвердил это своим примером. Да, и я не говорю, что этот код сильно ужасен. Просто при такой схеме все преимущества исключений пропадают. А недостатки (например неявность ошибок) остаются.

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

J>Да, на верхнем уровне, скажем, в обработчике кнопок меню: прилетело исключение — рассказал пользователю, что облом (с показом по требованию всей собранной исключениями через throw_with_nested информации), и работаешь себе дальше.
J>Потому что если можно продолжить нормальное исполнение программы после неудачного вызова функции на низком уровне, то это не исключительная ситуация по определению, правда?

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