эксепшины vs коды возврата
От: Vladik Россия  
Дата: 11.09.02 17:35
Оценка:
Привет!

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

Итак, если кратко: эксепшины имеют право на существование, но их применение следует ограничить исключительно исключительными ситуациями.
Примеры. Эксепшин на невозможность выделения памяти — это правильно. Ситуация однозначно исключительная (во всяком случае для 99% прог и для 99% кода оставшегося 1% прог) и свидетельствует о том, что все действительно очень плохо. Эксепшин на невозможность открытия файла, преобразовать строку в число и т.п. для библиотечных классов/функций — это неправильно. Потому как это заставляет программиста, использующего эти библиотечные функции явно ловить эксепшины даже тогда, когда код возврата ему абсолютно неинтересен.

Теперь подробнее, почему это так:
1) Синтаксис С++ в случае ловли эксепшинов заставляет городить:
value=default_value;
try
{
    value=f();
}
catch(exception)
{
}

вместо
value=default_value;
    f(&value);


В более практических случаях это здорово поганит читабельность. Кроме того, работает принцип: "на любом языке пишут так, как короче".

2) Компилятор С++ позволяет оставлять эксепшины без внимания:

void f()
{
    start_transaction();
    doit() ? commit_transaction() : rollback_transaction();
}


Программист, который пишет функцию doit() на очередной итерации разработки решил использовать в своей функции библиотечную функцию, кидающую эксепшин. Компилятор бессилен предупредить программиста, пишушего функцию f() о том, что некие действия могут быть вообще невыполнены, незавасимо от результата вызова doit().
Т.о. появляется фактор "неожиданности", который мне лично очень претит и который у меня ассоциируется с оператором goto

3) Отладка. Понять откуда и из-за чего пришел эксепшин в проге напичканной эксепшинами (без приема особых мер) бывает довольно затруднительно. А приходит он как раз из тех участков проги, в которых его никто не ожидает. В случае же непроверки кода возврата — прога просто вылетит на ближайшем assert'e.

4) Эффективность. С++ относится к тем языкам, используя которые, под эффективносью, в числе прочего, понимают и быстродействие и размер кода. Если на быстродействие эксепшины, как правило, и не сильно вляют, то код раздувают весьма эффективно.

5) Конструкторы/деструкторы. Распространяться не буду, уверен все и так поняли про что я. Опять упираемся в язык С++ как таковой. Т.е. все это заставить работать можно, но только зачем...

Все вышеперечисленные тезисы заставляют меня воздерживаться от применения механизма эксепшинов при разработке на С++. Поэтому просто приведу пару примеров тех редких случаев, когда я посчитал использование эксепшинов оправданным и использовал этот механизм.
1) Коммуникационный протокол связи по COM-порту. Эксепшины на ошибку COM-порта и "глобальный" таймаут приема/передачи. В обоих случаях дальнейшее продолжение связи бессмысленно и очень удобно кинуть эксепшин из "недр" и поймать его на самом "верху", нежели возиться с кучей кодов возврата.
2) Клиент, тупо вызывающий методы сервера. При любой ошибке вызова (не путать с результатом вызова) кидается эксепшин, который отлавливается и расшифровывается "наверху" в основном цикле приложения. При этом от клиента не требуется какой-либо особой реакци на эти ошибки (разве что показать юзеру). Т.е. юзер просто инициирует некое действие — клиент "переводит" его на сервер.
Как все запущенно...
Re: эксепшины vs коды возврата
От: Михаил Челноков Украина  
Дата: 11.09.02 17:57
Оценка:
Здравствуйте Vladik, Вы писали:

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


[skipped]

Добавлю еще одно неудобство — крайне трудно правильно обработать exception, если, конечно, это не глобальный сбой и ничего кроме "Ошибка, работать нельзя" ((с) некий Никитинский) сделать невозможно. Проверено на горьком опыте. Либо приходится обрабатывать их почти там же, где они генерируются (что вообще ставит под сомнение целесообразность их применения), либо на более верхнем уровне невозможно учесть условия/среду их возникновения, и, соответственно, правильно выкрутиться из ситуации.

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

V>1) Коммуникационный протокол связи по COM-порту. Эксепшины на ошибку COM-порта и "глобальный" таймаут приема/передачи. В обоих случаях дальнейшее продолжение связи бессмысленно и очень удобно кинуть эксепшин из "недр" и поймать его на самом "верху", нежели возиться с кучей кодов возврата.
V>2) Клиент, тупо вызывающий методы сервера. При любой ошибке вызова (не путать с результатом вызова) кидается эксепшин, который отлавливается и расшифровывается "наверху" в основном цикле приложения. При этом от клиента не требуется какой-либо особой реакци на эти ошибки (разве что показать юзеру). Т.е. юзер просто инициирует некое действие — клиент "переводит" его на сервер.

Обобщим — exception'ы целесообразно применять, когда их обработка не имеет смысла...
Re: эксепшины vs коды возврата
От: Bell Россия  
Дата: 12.09.02 07:15
Оценка: 13 (3)
Здравствуйте Vladik, Вы писали:

V>Привет!


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


Вообще я уже начал подобный (он щас в "философии")

V>Итак, если кратко: эксепшины имеют право на существование, но их применение следует ограничить исключительно исключительными ситуациями.

ИМХО именно для этого они и преднезначены.
V>Примеры. Эксепшин на невозможность выделения памяти — это правильно. Ситуация однозначно исключительная (во всяком случае для 99% прог и для 99% кода оставшегося 1% прог) и свидетельствует о том, что все действительно очень плохо.
Да уж
V>Эксепшин на невозможность открытия файла, преобразовать строку в число и т.п. для библиотечных классов/функций — это неправильно. Потому как это заставляет программиста, использующего эти библиотечные функции явно ловить эксепшины даже тогда, когда код возврата ему абсолютно неинтересен.
Не согласен. На мой взгляд разработчик библиотеки лучше знает, когда нужно, а когда не нужно обращать внимание на результат работы некоторой функции. В случае с исключением игнорировать его сложнее, чем код возврата.

V>Теперь подробнее, почему это так:

V>1) Синтаксис С++ в случае ловли эксепшинов заставляет городить:
V>
V>value=default_value;
V>try
V>{
V>    value=f();
V>}
V>catch(exception)
V>{
V>}
V>

V>вместо
V>
V>value=default_value;
V>    f(&value);
V>


А если нельзя по value определить — корректно отработала f или нет:?! В общем случай с atoi в чистом виде. Я согласен, что есть ситуации, когда на ошибку преобразования можно забить, и довольствоваться тем нулем, который она вернула. А если нет?! Не так давно я убил день на поиск именно такой ошибки!
V>В более практических случаях это здорово поганит читабельность. Кроме того, работает принцип: "на любом языке пишут так, как короче".

Ну, испоганить код можно всегда, и не только try-catch. Если же эти блоки натыканы на каждом шагу, то это по крайней мере наводит на подозрения...

V>2) Компилятор С++ позволяет оставлять эксепшины без внимания:


V>
V>void f()
V>{
V>    start_transaction();
V>    doit() ? commit_transaction() : rollback_transaction();
V>}
V>


V>Программист, который пишет функцию doit() на очередной итерации разработки решил использовать в своей функции библиотечную функцию, кидающую эксепшин. Компилятор бессилен предупредить программиста, пишушего функцию f() о том, что некие действия могут быть вообще невыполнены, незавасимо от результата вызова doit().

V>Т.о. появляется фактор "неожиданности", который мне лично очень претит и который у меня ассоциируется с оператором goto

Да, это не есть гут. Остается только внимательнее изучать документацию на библиотеку.

V>3) Отладка. Понять откуда и из-за чего пришел эксепшин в проге напичканной эксепшинами (без приема особых мер) бывает довольно затруднительно.

Повторюсь: "напичканная исключениями" программа наводит на подозрения. ИМХО сам термин "исключительная ситуация" указывает на то, что такие ситуации — нечто редкое...

V>А приходит он как раз из тех участков проги, в которых его никто не ожидает. В случае же непроверки кода возврата — прога просто вылетит на ближайшем assert'e.

При наличии этого assert'а (несколькими строчками выше кто говорил о возможности игнорирования кодов возврата... )

V>4) Эффективность. С++ относится к тем языкам, используя которые, под эффективносью, в числе прочего, понимают и быстродействие и размер кода. Если на быстродействие эксепшины, как правило, и не сильно вляют, то код раздувают весьма эффективно.


Да, к сожалению так

V>5) Конструкторы/деструкторы. Распространяться не буду, уверен все и так поняли про что я. Опять упираемся в язык С++ как таковой. Т.е. все это заставить работать можно, но только зачем...


Просто осторожнее надо быть в подобных местах.

Все вышеперечисленные тезисы заставляют меня воздерживаться от применения механизма эксепшинов при разработке на С++.
А меня нет.
V>Поэтому просто приведу пару примеров тех редких случаев, когда я посчитал использование эксепшинов оправданным и использовал этот механизм.
V>1) Коммуникационный протокол связи по COM-порту. Эксепшины на ошибку COM-порта и "глобальный" таймаут приема/передачи. В обоих случаях дальнейшее продолжение связи бессмысленно и очень удобно кинуть эксепшин из "недр" и поймать его на самом "верху", нежели возиться с кучей кодов возврата.

А что, такая ситуация (невозможность дальнейшей работы) возможно только при работе с портом?!
Я уже устал это повторять, но скажу еще раз: исключения — для исключительных ситуаций (т.е. для таких, после возникновения которых бессмысленно продолжать работу). Если же есть код типа:
пробуем что-то сделать
получилось - хорошо, едем дальше
не получилось (поймали исключение) - не беда, что-то подправляем и едем дальше

то явно речь не идет о какой-то исключительной ситуации, а просто о варианте поведения. Использовать здесь исключения по крайней мере неэффективно.

V>2) Клиент, тупо вызывающий методы сервера. При любой ошибке вызова (не путать с результатом вызова) кидается эксепшин, который отлавливается и расшифровывается "наверху" в основном цикле приложения. При этом от клиента не требуется какой-либо особой реакци на эти ошибки (разве что показать юзеру). Т.е. юзер просто инициирует некое действие — клиент "переводит" его на сервер.
Любите книгу — источник знаний (с) М.Горький
Re: эксепшины vs коды возврата
От: Patalog Россия  
Дата: 12.09.02 07:58
Оценка:
Здравствуйте Vladik, Вы писали:

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


В доконку хотел бы подкинуть пост из недр "знаменитого" топика "Выйти из двух циклов сразу" http://www.rsdn.ru/forum/Message.aspx?mid=61162&only=1
Автор: m.a.g.
Дата: 06.06.02

Как насчет данного случая? В плане применябельности эксепшенов.
Почетный кавалер ордена Совка.
Re[2]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 07:58
Оценка:
Здравствуйте Bell, Вы писали:

B>Вообще я уже начал подобный (он щас в "философии")

В философии это будут общие слова ни о чем Типа: "и то и то имеет смысл в зависимости от ситуации" и с этим трудно не согласится. Я же говорю, очень много чего зависит от средства разработки.

V>>Итак, если кратко: эксепшины имеют право на существование, но их применение следует ограничить исключительно исключительными ситуациями.

B>ИМХО именно для этого они и преднезначены.

Давай конкретизируем. Я не считаю невозможность открытия файла исключительной ситуацией.

[...]
V>>Эксепшин на невозможность открытия файла, преобразовать строку в число и т.п. для библиотечных классов/функций — это неправильно. Потому как это заставляет программиста, использующего эти библиотечные функции явно ловить эксепшины даже тогда, когда код возврата ему абсолютно неинтересен.
B>Не согласен. На мой взгляд разработчик библиотеки лучше знает, когда нужно, а когда не нужно обращать внимание на результат работы некоторой функции. В случае с исключением игнорировать его сложнее, чем код возврата.

Поему сложнее? Если пользователь библиотеки не удосужился обратить внимание на возможные возвращаеимые значение, он не удосужится и try/catch поставить. И все будет плохо (см.п. 2). А обработать код возврата синтаксически проще.

[...]
V>>value=default_value;
V>> f(&value);
V>>[/ccode]
B>А если нельзя по value определить — корректно отработала f или нет:?!

А оно и не надо в данном примере, т.к. есть default_value. И таких случаев не меньше, чем случаев, когда код возврата жизненно важен.

B>В общем случай с atoi в чистом виде.


B>Нет. У atoi нет дефолтового значения. Зато пользоваться ей удобнее.


B>Я согласен, что есть ситуации, когда на ошибку преобразования можно забить, и довольствоваться тем нулем, который она вернула. А если нет?!


А если нет — не надо пользоваться atoi. Я не понимаю, в чем проблема-то? И чем эксепшины здесь рулят?

[...]

V>>3) Отладка. Понять откуда и из-за чего пришел эксепшин в проге напичканной эксепшинами (без приема особых мер) бывает довольно затруднительно.

B>Повторюсь: "напичканная исключениями" программа наводит на подозрения.

Именно так и получится, если пихать эксепшины в библиотечные функции.

B>ИМХО сам термин "исключительная ситуация" указывает на то, что такие ситуации — нечто редкое...


Только для меня это нечто намного более редкое, чем для тебя

V>>А приходит он как раз из тех участков проги, в которых его никто не ожидает. В случае же непроверки кода возврата — прога просто вылетит на ближайшем assert'e.

B>При наличии этого assert'а (несколькими строчками выше кто говорил о возможности игнорирования кодов возврата... )

Нет, проверка кодов возврата и assert'ы — это разные вещи.

[...]
B>А что, такая ситуация (невозможность дальнейшей работы) возможно только при работе с портом?!

У меня таких ситуаций на практике было крайне мало. Как правило ошибка имеет смысл быть обрабатанной непосредственно на месте. И, как правило, это не фатальные ошибки.

Для возврата "наверх" из сильно вложенного алгоритма эксепшины действительно имеют смысл. Кидать их из библиотечных функций преобразования строки в число и т.п. — плохо. Я сам кину эксепшин, если моя задача подразумевает облом всего при неудачном преобразовании.
Как все запущенно...
Re[2]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 08:18
Оценка:
Здравствуйте Patalog, Вы писали:

P>В доконку хотел бы подкинуть пост из недр "знаменитого" топика "Выйти из двух циклов сразу" http://www.rsdn.ru/forum/Message.aspx?mid=61162&only=1
Автор: m.a.g.
Дата: 06.06.02

P>Как насчет данного случая? В плане применябельности эксепшенов.

Типичное извращение Особенно если циклы и затеяны был для того, чтобы найти эту самую исключительную "ситуацию". "На что только люди не идут, лишь бы goto не писать" (с) чей-то.
Как все запущенно...
Re[3]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 12.09.02 08:28
Оценка:
Здравствуйте Vladik, Вы писали:

V>В философии это будут общие слова ни о чем Типа: "и то и то имеет смысл в зависимости от ситуации" и с этим трудно не согласится. Я же говорю, очень много чего зависит от средства разработки.

Ок согласен.

V>>>Итак, если кратко: эксепшины имеют право на существование, но их применение следует ограничить исключительно исключительными ситуациями.

B>>ИМХО именно для этого они и преднезначены.

V>Давай конкретизируем. Я не считаю невозможность открытия файла исключительной ситуацией.

Это зависит от конкретного приложения и от конкретной ситуации.
[...]
V>Поему сложнее? Если пользователь библиотеки не удосужился обратить внимание на возможные возвращаеимые значение, он не удосужится и try/catch поставить. При этом прога сразу завалится, что сразу же наведет на некоторые размышления
Если же просто не поставили assert или не проверили код возврата, то прога завалится "там вдали за рекой", и истинную причину будет отыскать сложнее.
V>[...]
V>>>value=default_value;
V>>> f(&value);
V>>>[/ccode]
B>>А если нельзя по value определить — корректно отработала f или нет:?!

V>А оно и не надо в данном примере, т.к. есть default_value.

Это верно для данного примера

B>>В общем случай с atoi в чистом виде.


V>А если нет — не надо пользоваться atoi. Я не понимаю, в чем проблема-то? И чем эксепшины здесь рулят?

тем, что некорректная работа не остается без внимания

V>[...]


V>>>3) Отладка. Понять откуда и из-за чего пришел эксепшин в проге напичканной эксепшинами (без приема особых мер) бывает довольно затруднительно.

B>>Повторюсь: "напичканная исключениями" программа наводит на подозрения.

V>Именно так и получится, если пихать эксепшины в библиотечные функции.

Очень спорное утверждение. "Пихать эксепшины в библиотечные функции" можно очень по-разному.

B>>ИМХО сам термин "исключительная ситуация" указывает на то, что такие ситуации — нечто редкое...


V>Только для меня это нечто намного более редкое, чем для тебя

Ну что тут сказать

V>>>А приходит он как раз из тех участков проги, в которых его никто не ожидает. В случае же непроверки кода возврата — прога просто вылетит на ближайшем assert'e.

B>>При наличии этого assert'а (несколькими строчками выше кто говорил о возможности игнорирования кодов возврата... )

V>Нет, проверка кодов возврата и assert'ы — это разные вещи.


int nRetCode = someFunc();
assert(nRetCode != FAIL);



V>[...]

B>>А что, такая ситуация (невозможность дальнейшей работы) возможно только при работе с портом?!

V>У меня таких ситуаций на практике было крайне мало. Как правило ошибка имеет смысл быть обрабатанной непосредственно на месте. И, как правило, это не фатальные ошибки.

А у меня такие ситуации нередки. И это видимо — главная причина спора

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

Почему плохо? Конечно можно придумать флаг, который бы сигнализировал о результате, но всегда ли он будет проверяться? А вот с исключением прога завалится, и забывчивый программист отловит эту ситуацию в самом начале.
Любите книгу — источник знаний (с) М.Горький
Re[4]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 08:48
Оценка:
Здравствуйте Bell, Вы писали:

V>>Давай конкретизируем. Я не считаю невозможность открытия файла исключительной ситуацией.

B>Это зависит от конкретного приложения и от конкретной ситуации.

Мне трудно придумать такую ситуацию. В том смысле, что в любом случае мне придется обработать эту ошибку на месте и передать "наверх" более вразумительную информацию о том, что, где и как произошло. Если это не требуется и хватит простого сообщения об ошибке (типично для клиентского приложения) — тогда да. Но, как я уже говорил, у меня таки ситуции редки.

B>[...]

V>>Поему сложнее? Если пользователь библиотеки не удосужился обратить внимание на возможные возвращаеимые значение, он не удосужится и try/catch поставить.

B>При этом прога сразу завалится, что сразу же наведет на некоторые размышления

B>Если же просто не поставили assert или не проверили код возврата, то прога завалится "там вдали за рекой", и истинную причину будет отыскать сложнее.

В случае эксепшина истинную причину будет установить также сложно. И алгоритм функционирования проги также "поедет". Не вижу принципиальной разницы.

V>>А если нет — не надо пользоваться atoi. Я не понимаю, в чем проблема-то? И чем эксепшины здесь рулят?

B>тем, что некорректная работа не остается без внимания

Еще раз: не надо использовать atoi, если возможна некорректная работа. И не надо навязывать программисту проверки везде где надо и не надо — потому что это С++, а не VB.

V>>[...]

V>>Именно так и получится, если пихать эксепшины в библиотечные функции.
B>Очень спорное утверждение. "Пихать эксепшины в библиотечные функции" можно очень по-разному.

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

V>>Нет, проверка кодов возврата и assert'ы — это разные вещи.

B>
B>int nRetCode = someFunc();
B>assert(nRetCode != FAIL);
B>

B>

А это частный случай ассертов. И, кстати, в этом случае сразу ясно _где_ проблема. В отличие от.

V>>[...]

B>А у меня такие ситуации нередки. И это видимо — главная причина спора

Наверное.

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

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

Флаг это наихудшее из возможных решений.

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


Если она завалится на самом начале. А если нет, то он наконец найдет это место и с руганью засунет этот вызов в пустой try/catch.
Как все запущенно...
Re[3]: эксепшины vs коды возврата
От: Mink Россия  
Дата: 12.09.02 08:55
Оценка:
Здравствуйте Vladik, Вы писали:

[...]

V>>>Итак, если кратко: эксепшины имеют право на существование, но их применение следует ограничить исключительно исключительными ситуациями.

B>>ИМХО именно для этого они и преднезначены.

V>Давай конкретизируем. Я не считаю невозможность открытия файла исключительной ситуацией.


Твое личное дело О вкусах не спорят.

V>[...]

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

V>Поему сложнее? Если пользователь библиотеки не удосужился обратить внимание на возможные возвращаеимые значение, он не удосужится и try/catch поставить. И все будет плохо (см.п. 2). А обработать код возврата синтаксически проще.


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

V>[...]

V>>>value=default_value;
V>>> f(&value);
V>>>[/ccode]
B>>А если нельзя по value определить — корректно отработала f или нет:?!

V>А оно и не надо в данном примере, т.к. есть default_value. И таких случаев не меньше, чем случаев, когда код возврата жизненно важен.


А кто тебе сказал, что после неудачного выполнения f у тебя default_value останется?

B>>В общем случай с atoi в чистом виде.


B>>Нет. У atoi нет дефолтового значения. Зато пользоваться ей удобнее.


B>>Я согласен, что есть ситуации, когда на ошибку преобразования можно забить, и довольствоваться тем нулем, который она вернула. А если нет?!


V>А если нет — не надо пользоваться atoi. Я не понимаю, в чем проблема-то? И чем эксепшины здесь рулят?


А если нет, не надо и эксепшенами пользоваться. В чем проблема то?

V>[...]


V>>>3) Отладка. Понять откуда и из-за чего пришел эксепшин в проге напичканной эксепшинами (без приема особых мер) бывает довольно затруднительно.

B>>Повторюсь: "напичканная исключениями" программа наводит на подозрения.

V>Именно так и получится, если пихать эксепшины в библиотечные функции.


Именно так и получается, если нет четкого представления о логике обработки ошибок в программе.

B>>ИМХО сам термин "исключительная ситуация" указывает на то, что такие ситуации — нечто редкое...


V>Только для меня это нечто намного более редкое, чем для тебя


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

[...]

V>У меня таких ситуаций на практике было крайне мало. Как правило ошибка имеет смысл быть обрабатанной непосредственно на месте. И, как правило, это не фатальные ошибки.


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

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


Блин, а что она должна делать, если ей не удалось преобразовать строку в число? Возвращать 0? А почему не -1? Или ты считаешь, что 0 не может быть валидным результатом преобразования?
Сила, она в ньютонах
Re[5]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 12.09.02 09:18
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>В случае эксепшина истинную причину будет установить также сложно. И алгоритм функционирования проги также "поедет". Не вижу принципиальной разницы.

Ээээ...
Может я чего-то не понимаю, но если в отладчике после возникновения исключения взглянуть не call stack, то все вопросы типа "что" и "где" сразу отпадают.

V>Еще раз: не надо использовать atoi, если возможна некорректная работа. И не надо навязывать программисту проверки везде где надо и не надо — потому что это С++, а не VB.

А если эту atoi воткнули задолго до тебя?

V>>>[...]

V>>>Именно так и получится, если пихать эксепшины в библиотечные функции.
B>>Очень спорное утверждение. "Пихать эксепшины в библиотечные функции" можно очень по-разному.

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

Я в таких случаях смотрю call stack

V>>>Нет, проверка кодов возврата и assert'ы — это разные вещи.

B>>
B>>int nRetCode = someFunc();
B>>assert(nRetCode != FAIL);
B>>

B>>

V>А это частный случай ассертов. И, кстати, в этом случае сразу ясно _где_ проблема. В отличие от.

см. выше


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


V>Если она завалится на самом начале. А если нет, то он наконец найдет это место и с руганью засунет этот вызов в пустой try/catch.

Без исключений он с такой же руганью вставит в это место проверку кода возврата или asser
Любите книгу — источник знаний (с) М.Горький
Re[4]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 09:22
Оценка:
Здравствуйте Mink, Вы писали:

V>>Давай конкретизируем. Я не считаю невозможность открытия файла исключительной ситуацией.

M>Твое личное дело О вкусах не спорят.

У меня некая функция в процессе своей работы открывает файл. "Наверх" передается либо код возврата либо тот же эксепшин. Но в любом случае эксепшин на открытие файла не имеет никакого смысла "наверху".

V>>[...]

V>>Поему сложнее? Если пользователь библиотеки не удосужился обратить внимание на возможные возвращаеимые значение, он не удосужится и try/catch поставить. И все будет плохо (см.п. 2). А обработать код возврата синтаксически проще.

M>Не надо ненужность механизма обосновывать небрежностью (хотел вообще то другое слово использовать ) программиста.


Не понгял, ты вообще про что?

M>И потом, а если у тебя код возврата не один, а много?


И чего?

M>У тебя прикладная логика будет перемешана с логикой обработки ошибок, что явно не придаст программе стройности и надежности.


Стройности ей придаст обилие try/catch? Не смешно. Разбираться в проге с эксепшинами наоборот сложнее, т.к. не видно явно откуда и куда можно попасть. Почти как goto, только еще хуже goto не умеет между функциями скакать.

V>>А оно и не надо в данном примере, т.к. есть default_value. И таких случаев не меньше, чем случаев, когда код возврата жизненно важен.

M>А кто тебе сказал, что после неудачного выполнения f у тебя default_value останется?

А это стандарт де-факто для подобных функций.

V>>[...]

V>>Именно так и получится, если пихать эксепшины в библиотечные функции.
M>Именно так и получается, если нет четкого представления о логике обработки ошибок в программе.

Общие слова.

B>>>ИМХО сам термин "исключительная ситуация" указывает на то, что такие ситуации — нечто редкое...

V>>Только для меня это нечто намного более редкое, чем для тебя
M>Поскольку понятие "исключительная ситуация" формально не определено, то и спорить есть что либо она или нет бесполезено. Ты вообще читал, что у Страуструппа по этому поводу написано?

Нет. Но судя по тому, куда его несет в последнее время... ничего хорошего.

M>[...]

V>>У меня таких ситуаций на практике было крайне мало. Как правило ошибка имеет смысл быть обрабатанной непосредственно на месте. И, как правило, это не фатальные ошибки.
M>Как правило, "на месте" совершенно не ясен контекст в котором ошибка возникла.

Как правило он ясен и имеет смысл как раз на месте. Смотри пример в самом начале письма.

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


Давай свой пример. Мне так сходу не придумать. Желательно тоже с открытием файла. По-твоему отдельная функция вообще не знает что делает и все ошибки делегирует наверх. 90% — просто ошибка проектирования.

M>Если же ошибка может быть обработана сразу, так естественно ее стоит обрабатывать сразу и никто не заставляет тебя кидать эксепшен в такой ситуации.


Да, но только чтобы ее обработать сразу, писанины в случае с эксепшинами намного больше + потеря читабельности.

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

M>Блин, а что она должна делать, если ей не удалось преобразовать строку в число? Возвращать 0? А почему не -1? Или ты считаешь, что 0 не может быть валидным результатом преобразования?

Блин, что вы все пристали к atoi??? Более другая функция вернет ошибку, что непонятного???
Как все запущенно...
Re[6]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 09:31
Оценка:
Здравствуйте Bell, Вы писали:

V>>В случае эксепшина истинную причину будет установить также сложно. И алгоритм функционирования проги также "поедет". Не вижу принципиальной разницы.

B>Ээээ...
B>Может я чего-то не понимаю, но если в отладчике после возникновения исключения взглянуть не call stack, то все вопросы типа "что" и "где" сразу отпадают.

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

V>>Еще раз: не надо использовать atoi, если возможна некорректная работа. И не надо навязывать программисту проверки везде где надо и не надо — потому что это С++, а не VB.

B>А если эту atoi воткнули задолго до тебя?

Задолго до тебя могли много чего сделать не так как надо. Это не аргумент.

[...]
V>>А это частный случай ассертов. И, кстати, в этом случае сразу ясно _где_ проблема. В отличие от.
B>см. выше

Аналогично

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

V>>Если она завалится на самом начале. А если нет, то он наконец найдет это место и с руганью засунет этот вызов в пустой try/catch.
B>Без исключений он с такой же руганью вставит в это место проверку кода возврата или asser

А здесь еще есть чисто психологический момент У меня меньше раздражения по поводу своих ляпов (ассерт не поставил), нежели по поводу чужих (эксепшин кинули там, где я не ожидал).
Как все запущенно...
Re[7]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 12.09.02 09:48
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>>>В случае эксепшина истинную причину будет установить также сложно. И алгоритм функционирования проги также "поедет". Не вижу принципиальной разницы.

B>>Ээээ...
B>>Может я чего-то не понимаю, но если в отладчике после возникновения исключения взглянуть не call stack, то все вопросы типа "что" и "где" сразу отпадают.

V>Во-первых, в отладчике тебе придется отключить бряки на эксепшины, если ты эти эксепшины широко используешь.

Бряки я не отключаю, поскольку в моем понимании "широко" — это "не на каждом шагу". Случаются они у меня редко (ИМХО как и положено), поэтому не надоедают
V>Во-вторых, тестеров тоже будешь заставлять под отладчиком тестить?
Зачем? Пусть выявят условие при котором прога падает — дальше я сам все найду

V>Задолго до тебя могли много чего сделать не так как надо. Это не аргумент.

И все-таки обидно тратить кучу времени на поиск таких "тихих" ошибок

V>А здесь еще есть чисто психологический момент У меня меньше раздражения по поводу своих ляпов (ассерт не поставил)

try не поставил
V>, нежели по поводу чужих (эксепшин кинули там, где я не ожидал).
Насчет ожидал/не ожидал можно сказать и про тот же код возврата (ну кто бы мог подумать, что здесь ноль вернется — раньше ведь всегда единица верталась?!)
Это, как ты заметил, психология, которая суть вещь тонкая и непонятная.
Любите книгу — источник знаний (с) М.Горький
Re[8]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 10:03
Оценка:
Здравствуйте Bell, Вы писали:

V>>Во-первых, в отладчике тебе придется отключить бряки на эксепшины, если ты эти эксепшины широко используешь.

B>Бряки я не отключаю, поскольку в моем понимании "широко" — это "не на каждом шагу".
Случаются они у меня редко (ИМХО как и положено), поэтому не надоедают

Хм. А как же, например, чтение файла с игнорированием "неправильных" чисел?

V>>Во-вторых, тестеров тоже будешь заставлять под отладчиком тестить?

B>Зачем? Пусть выявят условие при котором прога падает — дальше я сам все найду

Я, конечно, заранее извиняюсь, но есть подозрение, что ты не отлаживал чего-то такого большого и глючного Когда баг проявляется один раз из ста запусков, и исключительно под 98-й виндой у одного тестера.
Как все запущенно...
Re[5]: эксепшины vs коды возврата
От: Mink Россия  
Дата: 12.09.02 10:16
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>>>Давай конкретизируем. Я не считаю невозможность открытия файла исключительной ситуацией.

M>>Твое личное дело О вкусах не спорят.

V>У меня некая функция в процессе своей работы открывает файл. "Наверх" передается либо код возврата либо тот же эксепшин. Но в любом случае эксепшин на открытие файла не имеет никакого смысла "наверху".


Не надо под "верхом" понимать MainFrame
Верхом может быть и фукция, из которой призводится вызов данной. А может, на одну выше. Или на две, без разницы. Суть в том, что ты можешь обработать это там, где тебе удобней, и не волочить за собой код возврата. Что же касается читабельности...

Вот пример кода с обработкой кодов ошибок:


if(OpenFile())
  if(MakeSomeString(str))
    if(WriteFile(str))
      CloseFile();
    else
      DoSomething();
  else
    DoSomethingElse();
else
  DoAnotherThihg();


А вот с try/catch:


try
  {
    OpenFile();
    MakeSomeString(str);
    WriteFile();
    CloseFile();
  }
catch(CFileExeption* ) {DoSomething();}
catch(COtherExeption*) {DoSomethingElse();}


Что наглядней и короче?

V>>>[...]

V>>>Поему сложнее? Если пользователь библиотеки не удосужился обратить внимание на возможные возвращаеимые значение, он не удосужится и try/catch поставить. И все будет плохо (см.п. 2). А обработать код возврата синтаксически проще.

M>>Не надо ненужность механизма обосновывать небрежностью (хотел вообще то другое слово использовать ) программиста.


V>Не понгял, ты вообще про что?

Это я про пользователь библиотеки, который не удосужится и try/catch поставить.

M>>У тебя прикладная логика будет перемешана с логикой обработки ошибок, что явно не придаст программе стройности и надежности.


V>Стройности ей придаст обилие try/catch? Не смешно. Разбираться в проге с эксепшинами наоборот сложнее, т.к. не видно явно откуда и куда можно попасть. Почти как goto, только еще хуже goto не умеет между функциями скакать.


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

V>>>А оно и не надо в данном примере, т.к. есть default_value. И таких случаев не меньше, чем случаев, когда код возврата жизненно важен.

M>>А кто тебе сказал, что после неудачного выполнения f у тебя default_value останется?

V>А это стандарт де-факто для подобных функций.


Да что ты говоришь? Доказательства в студию, плиз

V>>>[...]

V>>>Именно так и получится, если пихать эксепшины в библиотечные функции.
M>>Именно так и получается, если нет четкого представления о логике обработки ошибок в программе.

V>Общие слова.


Какое аргумент, такой и контраргумент.

B>>>>ИМХО сам термин "исключительная ситуация" указывает на то, что такие ситуации — нечто редкое...

V>>>Только для меня это нечто намного более редкое, чем для тебя
M>>Поскольку понятие "исключительная ситуация" формально не определено, то и спорить есть что либо она или нет бесполезено. Ты вообще читал, что у Страуструппа по этому поводу написано?

V>Нет. Но судя по тому, куда его несет в последнее время... ничего хорошего.


"Вчера опять от имени народа был осужден товарищ Пастернак. Его стихов мы не читали сроду, но и без них понятно, что он враг" (с) не помню.

M>>[...]

V>>>У меня таких ситуаций на практике было крайне мало. Как правило ошибка имеет смысл быть обрабатанной непосредственно на месте. И, как правило, это не фатальные ошибки.
M>>Как правило, "на месте" совершенно не ясен контекст в котором ошибка возникла.

V>Как правило он ясен и имеет смысл как раз на месте. Смотри пример в самом начале письма.


Смотри ответ на пример

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


V>Давай свой пример. Мне так сходу не придумать. Желательно тоже с открытием файла. По-твоему отдельная функция вообще не знает что делает и все ошибки делегирует наверх. 90% — просто ошибка проектирования.


Вот как раз у Страуструппа при обсуждении механизма ексепшенов приводятся конкретные примеры.

M>>Если же ошибка может быть обработана сразу, так естественно ее стоит обрабатывать сразу и никто не заставляет тебя кидать эксепшен в такой ситуации.


V>Да, но только чтобы ее обработать сразу, писанины в случае с эксепшинами намного больше + потеря читабельности.


Я что то не совсем понимаю. Если ты можешь обработать ошибку внутри функции, ты ее обрабатываешь без всякого эксепшена, если нет кидаешь его. Что значит "чтобы ее обработать сразу, писанины в случае с эксепшинами ...". Если ты хочешь сказать, что функция могла бы сигнализировать об ошибке не експшеном, а кодом возврата, так некоторые фукции, к примеру, CString возвращают. Что прикажешь понимать под кодом ошибки?

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


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

M>>Блин, а что она должна делать, если ей не удалось преобразовать строку в число? Возвращать 0? А почему не -1? Или ты считаешь, что 0 не может быть валидным результатом преобразования?

V>Блин, что вы все пристали к atoi??? Более другая функция вернет ошибку, что непонятного???


Ты сам ее привел в пример. Ты говоришь, что кидать из нее ексепшен неправильно. Внимание, вопрос: что она должна делать при невозможности выполнить преобразование.
Сила, она в ньютонах
Re[5]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 12.09.02 10:18
Оценка:
Здравствуйте Vladik, Вы писали:

Знаешь, у меня сложилось впечатление, что ты смотришь на исключения как на механизм организации логики работы программы. Что в корне не верно. Если следовать такому принципу, то действительно появится обилие блоков try-catch, которые изящности и читабельности отнюдь не добавят.
ИМХО главный прикол в использовании исключений — писать только логику, не засоряя код кучей ненужных однотипных проверок. Обработка же ошибок выносится в другое место. Тогда программа читается гораздо приятнее. Другое дело, что организовать программу таким образом сложнее. Но тут уж либо серьезно отнестись к проектированию, либо валить все в одну кучу. И касается это не только исключений.
Не знаю как тебя, а меня бесят конструкции типа
RetCode = someFunc1();
if(RetCode != GOOD)
   return RetCode;

...

RetCode = someFuncN();
if(RetCode != GOOD)
   return RetCode;


Да еще если этот RetCode начинает откуда-то из глубин всплывать. Это как раз и есть пример, когда на месте нет информации о том, что дальше делать. Если же такая инф-я есть, то и исключение бросать мсысла нет, а просто обработать все на месте, и ехать спокойно дальше.
Любите книгу — источник знаний (с) М.Горький
Re[9]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 12.09.02 10:26
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>>>Во-первых, в отладчике тебе придется отключить бряки на эксепшины, если ты эти эксепшины широко используешь.

B>>Бряки я не отключаю, поскольку в моем понимании "широко" — это "не на каждом шагу".
B>>Случаются они у меня редко (ИМХО как и положено), поэтому не надоедают

V>Хм. А как же, например, чтение файла с игнорированием "неправильных" чисел?

Устал повторять: бывает, что "неправильное" число можно спокойно игнорировать, а бывает — наоборот. Бывает, что ситуацию с "неправильным числом" можно обработать сразу на месте, а бывает — что нет.

V>Я, конечно, заранее извиняюсь, но есть подозрение, что ты не отлаживал чего-то такого большого и глючного Когда баг проявляется один раз из ста запусков, и исключительно под 98-й виндой у одного тестера.

Смею тебя заверить, что извиняешься не зря
Любите книгу — источник знаний (с) М.Горький
Re[6]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 11:44
Оценка:
Здравствуйте Mink, Вы писали:

V>>У меня некая функция в процессе своей работы открывает файл. "Наверх" передается либо код возврата либо тот же эксепшин. Но в любом случае эксепшин на открытие файла не имеет никакого смысла "наверху".

M>Не надо под "верхом" понимать MainFrame
M>Верхом может быть и фукция, из которой призводится вызов данной. А может, на одну выше. Или на две, без разницы. Суть в том, что ты можешь обработать это там, где тебе удобней, и не волочить за собой код возврата. Что же касается читабельности...

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

M>Вот пример кода с обработкой кодов ошибок:

M>
M>
M>if(OpenFile())
M>  if(MakeSomeString(str))
M>    if(WriteFile(str))
M>      CloseFile();
M>    else
M>      DoSomething();
M>  else
M>    DoSomethingElse();
M>else
M>  DoAnotherThihg();
M>


Позволю немного упростить пример:

if (!OpenFile())
  DoAnotherThihg();
else
{
  if(!WriteFile(str))
      DoSomething();

  CloseFile();
}


Т.е. CloseFile должно сработать независимо от успеха WriteFile

M>А вот с try/catch:



try
{
  OpenFile();

  try
  {
    WriteFile();
  }
  catch(CFileExeption* ) 
  {
      DoSomething();
  }

  CloseFile();
}
catch(CFileExeption* ) 
{  
  DoAnotherThihg();
}


M>Что наглядней и короче?


Ы?

[...]
V>>Стройности ей придаст обилие try/catch? Не смешно. Разбираться в проге с эксепшинами наоборот сложнее, т.к. не видно явно откуда и куда можно попасть. Почти как goto, только еще хуже goto не умеет между функциями скакать.

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


См. вышеприведенный пример. Переделай мне его с одним try/catch и без дублирования кода.

V>>>>А оно и не надо в данном примере, т.к. есть default_value. И таких случаев не меньше, чем случаев, когда код возврата жизненно важен.

M>>>А кто тебе сказал, что после неудачного выполнения f у тебя default_value останется?
V>>А это стандарт де-факто для подобных функций.
M>Да что ты говоришь? Доказательства в студию, плиз

Win32API

[...]
V>>Нет. Но судя по тому, куда его несет в последнее время... ничего хорошего.
M>"Вчера опять от имени народа был осужден товарищ Пастернак. Его стихов мы не читали сроду, но и без них понятно, что он враг" (с) не помню.

Я тоже могу придумать источник, которого ты не читал, и ссылаться на него в качестве доказательства. И чего?

M>>>[...]

V>>Как правило он ясен и имеет смысл как раз на месте. Смотри пример в самом начале письма.
M>Смотри ответ на пример

У тебя как раз на месте все и обрабатывается.

[...]
M>Вот как раз у Страуструппа при обсуждении механизма ексепшенов приводятся конкретные примеры.

Давай ссылку, мне интересно будет глянуть.

M>>>Если же ошибка может быть обработана сразу, так естественно ее стоит обрабатывать сразу и никто не заставляет тебя кидать эксепшен в такой ситуации.

V>>Да, но только чтобы ее обработать сразу, писанины в случае с эксепшинами намного больше + потеря читабельности.
M>Я что то не совсем понимаю. Если ты можешь обработать ошибку внутри функции, ты ее обрабатываешь без всякого эксепшена, если нет кидаешь его.

Я имел ввиду, что если мне надо обработать "на месте" OpenFile, который кидает эксепшин, то мне придется заворачивать его в try/catch, вместо простого if'a с return'ом.

[...]
V>>Блин, что вы все пристали к atoi??? Более другая функция вернет ошибку, что непонятного???
M>Ты сам ее привел в пример. Ты говоришь, что кидать из нее ексепшен неправильно. Внимание, вопрос: что она должна делать при невозможности выполнить преобразование.

Я привел ее в совершенно другом топике по совершенно другому поводу.
Как все запущенно...
Re[7]: эксепшины vs коды возврата
От: Mink Россия  
Дата: 12.09.02 12:03
Оценка:
Здравствуйте Vladik, Вы писали:

M>>А вот с try/catch:


V>

V>
V>try
V>{
V>  OpenFile();

V>  try
V>  {
V>    WriteFile();
V>  }
V>  catch(CFileExeption* ) 
V>  {
V>      DoSomething();
V>  }

V>  CloseFile();
V>}
V>catch(CFileExeption* ) 
V>{  
V>  DoAnotherThihg();
V>}
V>


M>>Что наглядней и короче?


V>Ы?



У меня было очень сильное подозрение, что ты их используешь именно так
Все, что я могу посоветовать, обратись к первоисточнику, может прояснится сознание
Сила, она в ньютонах
Re[10]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 12:05
Оценка:
Здравствуйте Bell, Вы писали:

V>>>>Во-первых, в отладчике тебе придется отключить бряки на эксепшины, если ты эти эксепшины широко используешь.

B>>>Бряки я не отключаю, поскольку в моем понимании "широко" — это "не на каждом шагу".
B>>>Случаются они у меня редко (ИМХО как и положено), поэтому не надоедают

V>>Хм. А как же, например, чтение файла с игнорированием "неправильных" чисел?

B>Устал повторять: бывает, что "неправильное" число можно спокойно игнорировать, а бывает — наоборот. Бывает, что ситуацию с "неправильным числом" можно обработать сразу на месте, а бывает — что нет.

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

V>>Я, конечно, заранее извиняюсь, но есть подозрение, что ты не отлаживал чего-то такого большого и глючного Когда баг проявляется один раз из ста запусков, и исключительно под 98-й виндой у одного тестера.

B>Смею тебя заверить, что извиняешься не зря

Пока ты меня не убедил
Как все запущенно...
Re[8]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 12:09
Оценка:
Здравствуйте Mink, Вы писали:

M>У меня было очень сильное подозрение, что ты их используешь именно так

M>Все, что я могу посоветовать, обратись к первоисточнику, может прояснится сознание

Ну покажи как правильно.
Как все запущенно...
Re[9]: эксепшины vs коды возврата
От: Mink Россия  
Дата: 12.09.02 12:23
Оценка:
Здравствуйте Vladik, Вы писали:

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


M>>У меня было очень сильное подозрение, что ты их используешь именно так

M>>Все, что я могу посоветовать, обратись к первоисточнику, может прояснится сознание

V>Ну покажи как правильно.


Страуструпп, Язык С++, издание 3, глава 14.
Сила, она в ньютонах
Re[10]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 12:30
Оценка:
Здравствуйте Mink, Вы писали:

V>>Ну покажи как правильно.

M>Страуструпп, Язык С++, издание 3, глава 14.

У меня нету под рукой 3-го издания Страуструпа, оставишь меня в невединии? Пример маленький, неужели так сложно переписать его правильно?
Как все запущенно...
Re[7]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 12.09.02 13:17
Оценка:
Здравствуйте Vladik, Вы писали:

V>Позволю немного упростить пример:


V>
V>if (!OpenFile())
V>  DoAnotherThihg();
V>else
V>{
V>  if(!WriteFile(str))
V>      DoSomething();

V>  CloseFile();
V>}
V>


V>Т.е. CloseFile должно сработать независимо от успеха WriteFile


M>>А вот с try/catch:


V>

V>
V>try
V>{
V>  OpenFile();

V>  try
V>  {
V>    WriteFile();
V>  }
V>  catch(CFileExeption* ) 
V>  {
V>      DoSomething();
V>  }

V>  CloseFile();
V>}
V>catch(CFileExeption* ) 
V>{  
V>  DoAnotherThihg();
V>}
V>



V>Ы?


Ну, постепенно проясняется причины нелюбви к исключениям
Ты хотя бы ради интереса смотрел на диаграмму "Exception classe" в MFC? ИМХО редкостное убожество. С такой системой исключений действительно трудно сделать что-либо номальное. Хотя даже здесь сожно обойтись одним try:

try
{
   OpenFile();
   WriteFile();
   CloseFile();
}
catch(CFileException* e)
{
   if(e->m_cause == /* ошибка открытия */)
      DoAnotherThihg();
   else if(e->m_cause == /* ошибка чтения/записи */)
   {
      DoSomething();
   }
}



конечно этот код не блещет изящностью, к тому же нужно разбираться с возможными значениями m_cause.
НО! Не стоит кричать "ислючения маст дай" из-за откровенно неудачных примеров.
Любите книгу — источник знаний (с) М.Горький
Re[8]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 12.09.02 13:35
Оценка:
Здравствуйте Bell, Вы писали:

B>Ну, постепенно проясняется причины нелюбви к исключениям

B>Ты хотя бы ради интереса смотрел на диаграмму "Exception classe" в MFC? ИМХО редкостное убожество.

Вообще нелюбовь к исключениям у меня пошла от VCL MFC, хоть и "редкостное убожество", как ты говоришь, но зато не злоупотребляет ими.

B>С такой системой исключений действительно трудно сделать что-либо номальное. Хотя даже здесь сожно обойтись одним try:


B>
B>try
B>{
B>   OpenFile();
B>   WriteFile();
B>   CloseFile();
B>}
B>catch(CFileException* e)
B>{
B>   if(e->m_cause == /* ошибка открытия */)
B>      DoAnotherThihg();
B>   else if(e->m_cause == /* ошибка чтения/записи */)
B>   {
B>      DoSomething();
B>   }
B>}
B>


А как же CloseFile?

B>конечно этот код не блещет изящностью, к тому же нужно разбираться с возможными значениями m_cause.

B>НО! Не стоит кричать "ислючения маст дай" из-за откровенно неудачных примеров.

Хорошо, типа я стал жертвой убожеств в лице MFC и VCL (или по поводу VCL будут возражения?). Каково же все-таки правильное решение с эксепшинами для данного примера с файлом? Кстати, понятно, что CloseFile будет делать деструктор класса файла, но тем не менее его явный вызов хотелось бы оставить как пример кода, который должен быть выполнен независимо от возникновения каких-то отдельных эксепшинов.
Как все запущенно...
Re[9]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 12.09.02 14:07
Оценка:
Здравствуйте Vladik, Вы писали:


V>А как же CloseFile?


V>Хорошо, типа я стал жертвой убожеств в лице MFC и VCL (или по поводу VCL будут возражения?). Каково же все-таки правильное решение с эксепшинами для данного примера с файлом? Кстати, понятно, что CloseFile будет делать деструктор класса файла, но тем не менее его явный вызов хотелось бы оставить как пример кода, который должен быть выполнен независимо от возникновения каких-то отдельных эксепшинов.


Лучший вариант — вообще поместить CloseFile после try — catch блока. Естественно, если он сам не бросает исключений, и если корректно работает на неоткрытом файле. Предвижу ехидные улыбки, но ничего лучшего для данного случая предложить не могу. При несоблюдении этих условий придется втыкать этот вызов в несколько мест, что плохо.
Любите книгу — источник знаний (с) М.Горький
Re: эксепшины vs коды возврата
От: Анатолий СССР  
Дата: 12.09.02 14:43
Оценка: 18 (3)
Несколько сентенций, с вашего позволения:

Конкретика:
Исключение — механизм оповещения клиентов о нарушении инвариантов поведения сервера или агента в контрактной (читай объектной) парадигме программирования (выделенное является ключевым). При структурном подходе другое дело — функциональная декомпозиция (функция), поэтому в качестве инструментов оповещения "клиентов" и использовались коды возврата и/или глобальные переменные.

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

Попытка вывода:
Каждый подход хорош на своем месте и в данных обстоятельствах (см. соотвественно п. Конкретика и п.Философия).

С уважением.
Re[10]: эксепшины vs коды возврата
От: m.a.g. Мальта http://dottedmag.net/
Дата: 13.09.02 09:39
Оценка:
Здравствуйте Bell, Вы писали:

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


B>Лучший вариант — вообще поместить CloseFile после try — catch блока. Естественно, если он сам не бросает исключений, и если корректно работает на неоткрытом файле. Предвижу ехидные улыбки, но ничего лучшего для данного случая предложить не могу. При несоблюдении этих условий придется втыкать этот вызов в несколько мест, что плохо.


А как же магические слова "выделение ресурса есть инициализация"? Либо в языке есть деструкторы, либо есть finally.
Re[11]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 13.09.02 09:58
Оценка:
Здравствуйте m.a.g., Вы писали:

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


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


B>>Лучший вариант — вообще поместить CloseFile после try — catch блока. Естественно, если он сам не бросает исключений, и если корректно работает на неоткрытом файле. Предвижу ехидные улыбки, но ничего лучшего для данного случая предложить не могу. При несоблюдении этих условий придется втыкать этот вызов в несколько мест, что плохо.


MAG>А как же магические слова "выделение ресурса есть инициализация"? Либо в языке есть деструкторы, либо

есть finally.
Там выше было замечание, что CloseFile надо вызвать явно (то что файл закрывается в деструкторе — это ясно)
Любите книгу — источник знаний (с) М.Горький
Re[7]: эксепшины vs коды возврата
От: Sergey Zhulin  
Дата: 13.09.02 10:21
Оценка:
Здравствуйте Vladik, Вы писали:

V>
V>try
V>{
V>  OpenFile();

V>  try
V>  {
V>    WriteFile();
V>  }
V>  catch(CFileExeption* ) 
V>  {
V>      DoSomething();
V>  }

V>  CloseFile();
V>}
V>catch(CFileExeption* ) 
V>{  
V>  DoAnotherThihg();
V>}
V>


На лицо структурное проектирование, к нему действительно трудно применить механизм исключений, но если подойти с точки зрения объектного проектирования, то исключения достаточно гармонично вовлекаются в логику программы, да и структура такой программы заметно изменяется. Например, для нашего примера у меня было бы нечто следующее:


class File
{
  public:
  File(){}
  ~File(){ CloseFile(); }
  open(){ OpenFile(); }
  write( Param params ){}
};

//....//
File file;
try
{
  file.open();
  file.write( someParam );
}
catch(FileOpeningFailed&  )
{
  DoSomething();
}
catch(CFileWritingFailed&  )
{
  DoAnotherThihg();
}


V>Ы?

Чтобы пользоваться исключениями надо и проектировать соответственно, а простая подмена проверки кода возврата на обработку исключений только испортит стройность кода и читабельность, рефакторинг нужен.
Re[12]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 13.09.02 10:29
Оценка:
Здравствуйте Bell, Вы писали:

MAG>>А как же магические слова "выделение ресурса есть инициализация"? Либо в языке есть деструкторы, либо

B>есть finally.

finally нет в стандарте, и с ним есть свои заморочки (кто-то выступал на эту тему).
Как все запущенно...
Re[8]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 13.09.02 10:41
Оценка:
Здравствуйте Sergey Zhulin, Вы писали:

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


Не надо таких высокопарных слов. Я привел простой пример. Естественно, изменив архитектуру можно переписать его так, чтобы с исключениями все было гладко. Однако, я изначально делал упор на вредность библиотечных исключений как раз из-за того, что используя уже готовые классы, их архитектуру ты уже не поменяешь нужным под твою задачу образом. Поэтому в конце концов все опять сведется к упавке во вложенные try/catch и прочим маразмам.
Как все запущенно...
Re[13]: эксепшины vs коды возврата
От: m.a.g. Мальта http://dottedmag.net/
Дата: 13.09.02 12:05
Оценка:
Здравствуйте Vladik, Вы писали:

MAG>>>А как же магические слова "выделение ресурса есть инициализация"? Либо в языке есть деструкторы, либо

B>>есть finally.

V>finally нет в стандарте, и с ним есть свои заморочки (кто-то выступал на эту тему).


Зато в стандарте есть деструкторы.
Разве исключения — это прерогатива С++?
Re[9]: эксепшины vs коды возврата
От: Sergey Zhulin  
Дата: 13.09.02 12:16
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>Не надо таких высокопарных слов. Я привел простой пример. Естественно, изменив архитектуру можно переписать его так, чтобы с исключениями все было гладко. Однако, я изначально делал упор на вредность библиотечных исключений как раз из-за того, что используя уже готовые классы, их архитектуру ты уже не поменяешь нужным под твою задачу образом. Поэтому в конце концов все опять сведется к упавке во вложенные try/catch и прочим маразмам.


А не надо простых примеров, если говоришь о глобальных вещах, типа "никогда не используй исключения в библиотеках". На оба подхода можно написать чушь со вложенными try/catch или протаскивая кучу кодов возврата с switch или if/else if/else и тд.

Участвую в разработке большого проекта, в котором присутствует большое число компонент и библиотек, разработанных внутри компании и третьими фирмами. Изначально была продумана стратегия обработки исключений. Ни одного места в исходниках нет со вложенными try/catch. Принимаю участие в code review, поэтому могу говорить практически за весь исходный код проекта, за исключением небольших компонент разработанных очень давно или на Си.

Нету вредности исключений пробрасываемых из библиотек, есть вредность плохо написанных библиотек, в которых применение исключений приводит к кошмару.

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

С уважением Сергей.
Re[14]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 13.09.02 12:40
Оценка:
Здравствуйте m.a.g., Вы писали:

V>>finally нет в стандарте, и с ним есть свои заморочки (кто-то выступал на эту тему).

MAG>Зато в стандарте есть деструкторы.

Я рад. Предлагаешь весь код, который должен быть выполнен в случае неудачи упаковывать в деструктор?

MAG>Разве исключения — это прерогатива С++?


См. самое первое мое письмо. Обсуждаем исключительно С++.
Как все запущенно...
Re[2]: эксепшины vs коды возврата
От: Sergey Zhulin  
Дата: 13.09.02 12:47
Оценка:
Здравствуйте Patalog, Вы писали:

P>В доконку хотел бы подкинуть пост из недр "знаменитого" топика "Выйти из двух циклов сразу" http://www.rsdn.ru/forum/Message.aspx?mid=61162&only=1
Автор: m.a.g.
Дата: 06.06.02

P>Как насчет данного случая? В плане применябельности эксепшенов.

Я встречал и более корявый код:


//..
try
{
  if( RIGHT_VALUE != someVariable ) throw SomeException;
}
catch(SomeException&)
{
  someVariable = RIGHT_VALUE;
}
//..


Этот кусок кода многое говорит о разработчике, но ничего за и/или против использования механизма исключений.
Re[10]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 13.09.02 12:51
Оценка:
Здравствуйте Sergey Zhulin, Вы писали:

SZ>Участвую в разработке большого проекта, в котором присутствует большое число компонент и библиотек, разработанных внутри компании и третьими фирмами. Изначально была продумана стратегия обработки исключений. Ни одного места в исходниках нет со вложенными try/catch. Принимаю участие в code review, поэтому могу говорить практически за весь исходный код проекта, за исключением небольших компонент разработанных очень давно или на Си.


Я тоже не вчера родился. Мой опыт говорит, что исключения в С++ ничем кроме геморроя с try/catch и вылетом неизвестно откуда неизвестно куда не оборачиваются. За редким исключением.

SZ>Нету вредности исключений пробрасываемых из библиотек, есть вредность плохо написанных библиотек, в которых применение исключений приводит к кошмару.


По поводу плохих библиотек я уже писал. Возможно когда я увижу правильную библиотеку, я изменю свое мнение.

SZ>И на последок, я всегда был против категоричного утверждения, что какие-то конструкции хуже других. Все надо к месту применять. Существует много ситуаций, когда одна или другая конструкция лучше подходит, ну так и используй ее.


Именно так я и делаю. Я не против исключений вообще, я против маразмов типа:


bool success=true;
    try
    {
        f();
    }
    catch(exception)
    {
        success=false;
    }

    if (success)
    {
    ...
    }
    else
    {
    ...
    }


которые неизбежно получаются при широком использовании эксепшинов, особенно в левосторонних библиотеках.
Как все запущенно...
Re[11]: эксепшины vs коды возврата
От: Sergey Zhulin  
Дата: 13.09.02 13:12
Оценка:
Здравствуйте Vladik, Вы писали:

V>Я тоже не вчера родился. Мой опыт говорит, что исключения в С++ ничем кроме геморроя с try/catch и вылетом неизвестно откуда неизвестно куда не оборачиваются. За редким исключением.


Хорошо. Тогда как с помощью кода возврата обеспечить инвариант класса, если проблемы могут возникнуть при конструировании объекта без использования отложенной инициализации и членов индикаторов?

Например:

class SomeClass
{
  bool m_bInit;
public:
  SomeClass():m_bInit(false){}
  int init()
  {
    bool bRet = true;
    if( !bInit )
    {
      //Инициализация
      if( bProblem ) bRet = false;
    }
    return bRet;
  }

  bool someFunction()
  {
    if( !bInit ) return false;
    //..выполнить действия
    return true;
  }
};


так вот, получается, что для обеспечения инварианта каждый метод класса должен содержать проверку индикаторов. Инициализацию невозможно поместить в конструктор, так как нету кода возврата. Это простейший случай, для инициализации объекта, но если после исполнения какого-нибудь метода инвариант нарушен, то с таким объектом можно продолжать работать не зная о том, что он более не валиден, и никто об этом не просигналит, если забыли проверить возвращенное значение.
Re[15]: эксепшины vs коды возврата
От: Sergey Россия  
Дата: 13.09.02 13:21
Оценка:
Здравствуйте Vladik, Вы писали:

V>>>finally нет в стандарте, и с ним есть свои заморочки (кто-то выступал на эту тему).

MAG>>Зато в стандарте есть деструкторы.

V>Я рад. Предлагаешь весь код, который должен быть выполнен в случае неудачи упаковывать в деструктор?


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


try
{
   struct closer
   {
       closer(A &owner) : _a(owner) {}
       ~closer() { _a.CloseFile(); }
   private:
       A _a;
   };

   OpenFile();
   closer(*this);
   WriteFile();
}
catch(CFileException* e)
{
   if(e->m_cause == /* ошибка открытия */)
      DoAnotherThihg();
   else if(e->m_cause == /* ошибка чтения/записи */)
   {
      DoSomething();
   }
}
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[12]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 13.09.02 13:27
Оценка: -1
Здравствуйте Sergey Zhulin, Вы писали:

SZ>Хорошо. Тогда как с помощью кода возврата обеспечить инвариант класса, если проблемы могут возникнуть при конструировании объекта без использования отложенной инициализации и членов индикаторов?


Кстати, опять возвращаясь к моему первому письму — исключения в конструкторах в С++ как-бы есть, но работают настолько криво, что все-равно лучше их там не использовать.

SZ>Например:


SZ>class SomeClass

SZ>{
SZ> bool m_bInit;

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

SZ>public:

SZ> SomeClass():m_bInit(false){}
SZ> int init()
SZ> {
SZ> bool bRet = true;
SZ> if( !bInit )
SZ> {
SZ> //Инициализация
SZ> if( bProblem ) bRet = false;
SZ> }
SZ> return bRet;
SZ> }

SZ> bool someFunction()

SZ> {
SZ> if( !bInit ) return false;

assert(bInit);

SZ> //..выполнить действия

SZ> return true;
SZ> }
SZ>};

SZ>[/ccode]


SZ>так вот, получается, что для обеспечения инварианта каждый метод класса должен содержать проверку индикаторов.


Это вполне нормально.

SZ>Инициализацию невозможно поместить в конструктор, так как нету кода возврата. Это простейший случай, для инициализации объекта, но если после исполнения какого-нибудь метода инвариант нарушен, то с таким объектом можно продолжать работать не зная о том, что он более не валиден, и никто об этом не просигналит, если забыли проверить возвращенное значение.


Отлавливается сразу при отладке, как показано выше.
Как все запущенно...
Re[16]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 13.09.02 13:31
Оценка:
Здравствуйте Sergey, Вы писали:

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


[...]

И "это" лучше if/else??? Вопросов больше не имею (с)
Как все запущенно...
Re[17]: эксепшины vs коды возврата
От: Sergey Россия  
Дата: 13.09.02 13:44
Оценка:
Здравствуйте Vladik, Вы писали:

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


Там вкралась ошибка: естественно, должно быть не

closer(*this);


а
closer somename(*this);


V>И "это" лучше if/else??? Вопросов больше не имею (с)


"Это" гораздо лучше if/else по одной простой причине — какая бы у тебя сложная функция не была, сколько бы раз ты внутри нее не написал return, ты не сумеешь забыть закрыть файл — об этом позаботиться компилятор. Впрочем, с файлами обычно таких проблем не возникает. А вообще это в C++ стандартная техника освобождения ресурса (захват, правда, обычно делают в конструкторе).
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[18]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 13.09.02 14:05
Оценка:
Здравствуйте Sergey, Вы писали:

S>Там вкралась ошибка: естественно, должно быть не


Вот-вот. Да, так делать теоретически правильнее, и С++ это позволяет, но... ведь это же изврат для таких тривиальных задач, неужели сам не видишь?

[...]
S>"Это" гораздо лучше if/else по одной простой причине — какая бы у тебя сложная функция не была, сколько бы раз ты внутри нее не написал return, ты не сумеешь забыть закрыть файл — об этом позаботиться компилятор.

Если получается настолько сложная функция, что начинают иметь смысл "такие" вещи — то имеет смысл задуматься над декомпозицией.

S>Впрочем, с файлами обычно таких проблем не возникает. А вообще это в C++ стандартная техника освобождения ресурса (захват, правда, обычно делают в конструкторе).


Не надо путать ресурсы, для которых всегда имеет смысл написать враппер, и "общий" код, который должен быть выполнен в случае эксепшина.
Как все запущенно...
Re[11]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 13.09.02 14:51
Оценка:
Здравствуйте Vladik, Вы писали:


V>Я тоже не вчера родился. Мой опыт говорит, что исключения в С++ ничем кроме геморроя с try/catch и вылетом неизвестно откуда неизвестно куда не оборачиваются. За редким исключением.


При всем уважении, твой опыт — это только твой опыт.
Мой опыт говорит, что при нормальном проектировании исключения весьма полезны (заметь я не говорю о том, что их нужно использовать всегда)

SZ>>Нету вредности исключений пробрасываемых из библиотек, есть вредность плохо написанных библиотек, в которых применение исключений приводит к кошмару.


V>По поводу плохих библиотек я уже писал. Возможно когда я увижу правильную библиотеку, я изменю свое мнение.


Я надеюсь, что с тобой это когда-нибудь случиться

SZ>>И на последок, я всегда был против категоричного утверждения, что какие-то конструкции хуже других. Все надо к месту применять. Существует много ситуаций, когда одна или другая конструкция лучше подходит, ну так и используй ее.


V>Именно так я и делаю. Я не против исключений вообще, я против маразмов типа:


V>

V>
V>bool success=true;
V>    try
V>    {
V>        f();
V>    }
V>    catch(exception)
V>    {
V>        success=false;
V>    }

V>    if (success)
V>    {
V>    ...
V>    }
V>    else
V>    {
V>    ...
V>    }
V>


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

Это маразм, но вызван он не использование исключений вообще, а кривостью проектирования.
Любите книгу — источник знаний (с) М.Горький
Re[13]: эксепшины vs коды возврата
От: MaximE Великобритания  
Дата: 13.09.02 21:16
Оценка:
Здравствуйте Vladik, Вы писали:

Мое мнение, что все-таки ключевое в исключениях это механизм раскрутки стека, то что ставит их на уровень выше кодов возврата при использовании "выделение есть инициализация".

V>Кстати, опять возвращаясь к моему первому письму — исключения в конструкторах в С++ как-бы есть, но работают настолько криво, что все-равно лучше их там не использовать.


Что значит криво? Приведи пример. Исключения в конструкторах честно вызывают деструкторы всех созданных к моменту исключения членов и базовых классов.
Re[3]: эксепшины vs коды возврата
От: Patalog Россия  
Дата: 14.09.02 07:05
Оценка:
Здравствуйте Sergey Zhulin, Вы писали:

P>>В доконку хотел бы подкинуть пост из недр "знаменитого" топика "Выйти из двух циклов сразу" http://www.rsdn.ru/forum/Message.aspx?mid=61162&only=1
Автор: m.a.g.
Дата: 06.06.02

P>>Как насчет данного случая? В плане применябельности эксепшенов.

SZ>Я встречал и более корявый код:


Ну, насчет корявости ты загнул, имхо. Мне понравилось. Правда в _данном_ случае это не оправдано.
Почетный кавалер ордена Совка.
Re[14]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 16.09.02 07:01
Оценка:
Здравствуйте MaximE, Вы писали:

ME>Мое мнение, что все-таки ключевое в исключениях это механизм раскрутки стека, то что ставит их на уровень выше кодов возврата при использовании "выделение есть инициализация".


Это не всегда удобно. Пример приводился.

V>>Кстати, опять возвращаясь к моему первому письму — исключения в конструкторах в С++ как-бы есть, но работают настолько криво, что все-равно лучше их там не использовать.


ME>Что значит криво? Приведи пример. Исключения в конструкторах честно вызывают деструкторы всех созданных к моменту исключения членов и базовых классов.


Я не пользуюсь исключениями в конструкторах Мне достаточно почитать высказывания людей, с этим сталкивавшихся. В частности, было что-то типа: "не видел еще ни одного компилятора, у которого бы не было проблем с исключениями в конструкторе".
Как все запущенно...
Re[13]: эксепшины vs коды возврата
От: Sergey Zhulin  
Дата: 16.09.02 07:07
Оценка:
Здравствуйте Vladik, Вы писали:

V>Кстати, опять возвращаясь к моему первому письму — исключения в конструкторах в С++ как-бы есть, но работают настолько криво, что все-равно лучше их там не использовать.


Что значит работают криво? Не раскручивается стек? Не вызываются деструкторы при раскрутке стека?

SZ>>так вот, получается, что для обеспечения инварианта каждый метод класса должен содержать проверку индикаторов.


V>Это вполне нормально.


Кому как, для меня это не нормально. Инвариант, это значит, что объект не должен существовать в не валидном состоянии, он даже не должен быть сконструирован, это исключительная ситуация.

SZ>>Инициализацию невозможно поместить в конструктор, так как нету кода возврата. Это простейший случай, для инициализации объекта, но если после исполнения какого-нибудь метода инвариант нарушен, то с таким объектом можно продолжать работать не зная о том, что он более не валиден, и никто об этом не просигналит, если забыли проверить возвращенное значение.


V>Отлавливается сразу при отладке, как показано выше.


Хочу предложить уважаемым участникам форума в этой ветке вывести плюсы и минусы каждого подхода вместо бесполезного спора. В результате получится что-то типа hints для конкретных ситуаций.

С уважением,
Сергей Жулин.
Re[14]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 16.09.02 07:19
Оценка:
Здравствуйте Sergey Zhulin, Вы писали:

SZ>Кому как, для меня это не нормально. Инвариант, это значит, что объект не должен существовать в не валидном состоянии, он даже не должен быть сконструирован, это исключительная ситуация.


Тогда можно для конструирования использовать Create(), а конструкторы засунуть в private.

[...]
SZ>Хочу предложить уважаемым участникам форума в этой ветке вывести плюсы и минусы каждого подхода вместо бесполезного спора. В результате получится что-то типа hints для конкретных ситуаций.

Минусы по-пунктно уже были изложены в самом первом моем письме. Пусть плюсы кто-нибудь другой опишет.
Как все запущенно...
Re[15]: эксепшины vs коды возврата
От: Sergey Zhulin  
Дата: 16.09.02 07:22
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>Я не пользуюсь исключениями в конструкторах Мне достаточно почитать высказывания людей, с этим сталкивавшихся. В частности, было что-то типа: "не видел еще ни одного компилятора, у которого бы не было проблем с исключениями в конструкторе".


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

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

Сергей.
Re[16]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 16.09.02 07:54
Оценка:
Здравствуйте Sergey Zhulin, Вы писали:

SZ>Это не довод,


Да, это не довод, но учитывать стоит.

SZ>давай конкретные описания проблем. Зачем организовано это обсуждение? Ты хочешь всех убедить в бесполезности исключений или просто поболтать?


Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".
Как все запущенно...
Re[17]: эксепшины vs коды возврата
От: Sergey Zhulin  
Дата: 16.09.02 08:03
Оценка:
Здравствуйте Vladik, Вы писали:

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


SZ>>Это не довод,


V>Да, это не довод, но учитывать стоит.

Что учитывать-то?

SZ>>давай конкретные описания проблем. Зачем организовано это обсуждение? Ты хочешь всех убедить в бесполезности исключений или просто поболтать?


V>Я не пользуюсь исключениями в конструкторах Мне достаточно почитать высказывания людей, с этим сталкивавшихся. В частности, было что-то типа: "не видел еще ни одного компилятора, у которого бы не было проблем с исключениями в конструкторе".


V>Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".


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

Сергей.
Re[18]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 16.09.02 08:09
Оценка:
Здравствуйте Sergey Zhulin, Вы писали:

SZ>>>Это не довод,

V>>Да, это не довод, но учитывать стоит.
SZ>Что учитывать-то?

Глюки конкретных компиляторов, если ты ими пользуешься.

[...]
V>>Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".
SZ>Влад, определись. То конструкторы, то деструкторы...

Одна фигня.

SZ>Назови компиляторы и их проблемы при бросании исключений из конструкторов.


Поищи сам, вот в этом самом форуме. Мне влом. Упоминались конкретные компиляторы.
Как все запущенно...
Re[19]: эксепшины vs коды возврата
От: Sergey Zhulin  
Дата: 16.09.02 08:14
Оценка:
Здравствуйте Vladik, Вы писали:

V>Поищи сам, вот в этом самом форуме. Мне влом. Упоминались конкретные компиляторы.


Ну тогда ты не прав. Почему? Поищи сам в форуме.
Парни. Давай-те следующее, интересное обсуждение начнем

Сергей.
Re[20]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 16.09.02 08:17
Оценка:
Здравствуйте Sergey Zhulin, Вы писали:

V>>Поищи сам, вот в этом самом форуме. Мне влом. Упоминались конкретные компиляторы.

SZ>Ну тогда ты не прав. Почему? Поищи сам в форуме.

Может я и не прав, но проблемы будут у тебя

SZ>Парни. Давай-те следующее, интересное обсуждение начнем


Ну что ж, каждый остался при своем. Чего и следовало ожидать.
Как все запущенно...
Re[17]: эксепшины vs коды возврата
От: MaximE Великобритания  
Дата: 16.09.02 12:02
Оценка:
Здравствуйте Vladik, Вы писали:

V>Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".


Исключение в деструкторе — грубая ошибка.
Re[18]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 16.09.02 12:06
Оценка:
Здравствуйте MaximE, Вы писали:

V>>Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".

ME>Исключение в деструкторе — грубая ошибка.

Угу. Неотлавливаемая компилятором. Причем чем меньше источников эксепшинов — тем меньше вероятность ее возникновения.
Как все запущенно...
Re[19]: эксепшины vs коды возврата
От: MaximE Великобритания  
Дата: 16.09.02 12:14
Оценка: 5 (1)
Здравствуйте Vladik, Вы писали:

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


V>>>Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".

ME>>Исключение в деструкторе — грубая ошибка.

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


Можно никаких методов и функций не вызывать, объектов не создавать — тогда даже коды возврата не нужны .
Re[17]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 16.09.02 13:27
Оценка:
Здравствуйте Vladik, Вы писали:


V>Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".


Можно место в стандарте, где это написано?
Любите книгу — источник знаний (с) М.Горький
Re[19]: эксепшины vs коды возврата
От: jazzer Россия Skype: enerjazzer
Дата: 16.09.02 13:36
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>>>Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".

ME>>Исключение в деструкторе — грубая ошибка.

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


Логика железная :)

а чем меньше указателей и работы с динамической помятью — тем меньше вероятность, что мы получим access violation.
Это — аргумент в пользу отказа от указателей?
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]: эксепшины vs коды возврата
От: jazzer Россия Skype: enerjazzer
Дата: 16.09.02 13:38
Оценка:
V>[...]
V>>>Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".
SZ>>Влад, определись. То конструкторы, то деструкторы...

V>Одна фигня.


совершенно не одна фигня.
Вспомните доводы против выбрасывания исключений из деструкторов и попытайтесь хоть один из них применить к конструкторам.
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]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 16.09.02 13:57
Оценка:
Здравствуйте jazzer, Вы писали:

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

J>Логика железная

Только так.

J>а чем меньше указателей и работы с динамической помятью — тем меньше вероятность, что мы получим access violation.


Безусловно.

J>Это — аргумент в пользу отказа от указателей?


Да. Именно поэтому существуют более другие языки. В некоторых из них, кстати, и механизм эксепшинов реализован более правильно.
Как все запущенно...
Re[20]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 16.09.02 13:59
Оценка:
Здравствуйте jazzer, Вы писали:

J>совершенно не одна фигня.

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

Доводы другие, а проблемы все те же...
Как все запущенно...
Re[18]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 16.09.02 14:02
Оценка:
Здравствуйте Bell, Вы писали:

V>>Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".

B>Можно место в стандарте, где это написано?

Уел.
15.2.3. "...If a destructor called during stack unwinding exits with an exception, terminate is called...".

Это решает проблему?
Как все запущенно...
Re[21]: :)))
От: jazzer Россия Skype: enerjazzer
Дата: 16.09.02 14:08
Оценка:
Здравствуйте Vladik, Вы писали:

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


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

J>>Логика железная :)

V>Только так.


J>>а чем меньше указателей и работы с динамической помятью — тем меньше вероятность, что мы получим access violation.


V>Безусловно.


J>>Это — аргумент в пользу отказа от указателей?


V>Да. Именно поэтому существуют более другие языки. В некоторых из них, кстати, и механизм эксепшинов реализован более правильно.


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

Все определяется кривизной рук разработчика.

Если человек в жизни не использовал эксепшны, а потом прочитал книжку "С++ за 21 час" и начал писать такой код, который Вы приводили в примерах, то это говорит не о том, что механизм (или язык) плохой, а о тот, что квалификация программера не дотягивает.


Да, еще, конечно, можно поговорить о том, что в java это "лучше/короче/толще/больше градусов" (с)
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[22]: :)))
От: Vladik Россия  
Дата: 16.09.02 14:17
Оценка:
Здравствуйте jazzer, Вы писали:

J>>>Это — аргумент в пользу отказа от указателей?

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

Не уловил я связи... И на VB можно запороть очень важные данные.

J>Все определяется кривизной рук разработчика.

J>Если человек в жизни не использовал эксепшны, а потом прочитал книжку "С++ за 21 час" и начал писать такой код, который Вы приводили в примерах, то это говорит не о том, что механизм (или язык) плохой, а о тот, что квалификация программера не дотягивает.

Действительно железная логика

J>Да, еще, конечно, можно поговорить о том, что в java это "лучше/короче/толще/больше градусов" (с)


А вот это как раз мне неинтересно.
Как все запущенно...
Re[8]: эксепшины vs коды возврата
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 16.09.02 14:27
Оценка:
Exeption-ы очень удобны при "транзакционной" логике программы (т.е. если не выполнилось какое-то действие, то не надо выполнять и все последующие), а вот что делать, если хочется, чтобы функция продолжала работать дальше, даже если предыдущая часть кода сломалась:

При использование exception-ов получается следующий код:

void Save()
{
  try
  {
    WriteLog("Save");
  }
  catch (...)
  {
  }
  string filename = "out.dat";
  try
  {
    filename = GetFileName();
  }
  catch (...)
  {
  }

  File file (filename);
  file.Write (data);
}

//А функция WriteLog выглядит как-нибудь так
void WriteLog(string s)
{
  File file ("log.dat"); //здесь 
  file.Write (s);        //или здесь может выскочить exception
}

//А функция GetFileName() берет название файла, например, из конфигурационного файла:
string GetFileName()
{
  File file ("config.dat"); //здесь опять же может выскочить exception
  return file.ReadLine();
}



p.s. Самое плохое, что ни в одном языке нет даже простейшего способа скипнуть exception...
Re[19]: эксепшины vs коды возврата
От: Bell Россия  
Дата: 16.09.02 14:33
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>>>Я просто высказал свое мнение. Конкретная проблема — неотловленный эксепшин в деструкторе приводит к "undefined behaviour".

B>>Можно место в стандарте, где это написано?

V>Уел.


V>15.2.3. "...If a destructor called during stack unwinding exits with an exception, terminate is called...".

V>Это решает проблему?

Ну теперь снято обвинение в "undefined behaviour"
Любите книгу — источник знаний (с) М.Горький
Re[9]: эксепшины vs коды возврата
От: Юнусов Булат Россия  
Дата: 16.09.02 19:29
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>p.s. Самое плохое, что ни в одном языке нет даже простейшего способа скипнуть exception...


Это и самое хорошее. Про код возврата можно забыть а ексепшен пнет хочется этого или нет.
Другое дело ожидает ли программер что его пнут или нет
Я когда чего отлаживаю то в коде который может кинуть ексепшен я его кидаю насильственно — чтоб посмотреть где оно вылезет и что можно сделать дальше. В общем обрабатываю ситуацию по принципу ежли чего плохое может случится то оно случится обязательно.
Re[9]: эксепшины vs коды возврата
От: Sergey Zhulin  
Дата: 17.09.02 06:27
Оценка:
Здравствуйте DarkGray, Вы писали:

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

Вот немного переписаный кусок кода:


void writeLog( const std::string& strLog )
{
  try
  {
    File file ("log.dat");
    file.Write (s);
  }
  catch(...)
  {
    // assertion для debug версии.
  }
}

class Data
{
  std::string getDataFileName()
  {
    std::string fileName = "out.dat";

    try
    {
      fileName = ... //получение имени файла
    }
    catch(...)
    {
      writeLog("Exception when trying to get file name for data");
      // assertion для debug версии.
    }
    return fileName
  }
public:
  void write( const Param& param )
  {
    File file( getDataFileName() )
    file.write( param );
  }
  Param param read()
  {
    File file( getDataFileName() )
    return file.read();
  }
}

void save()
{
  writeLog("Save");
  try
  {
    Data data;
    data.write();
  }
  catch(...)
  {
    writeLog("Exception in 'save' function");
  }
}

void load()
{
  writeLog("Load");
  try
  {
    Data data;
    data.read();
  }
  catch(...)
  {
    writeLog("Exception in 'load' function");
  }
}


намеренно не стал детально прорабатывать производительность, поэтому при вызове writeLog постоянно создается и уничтожается объект класса File, не об этом сейчас разговор.

DG>p.s. Самое плохое, что ни в одном языке нет даже простейшего способа скипнуть exception...


и не надо. Не для этого они сделаны чтоб их скипали.

Сергей.
Re[10]: эксепшины vs коды возврата
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.09.02 06:40
Оценка:
Здравствуйте Sergey Zhulin, Вы писали:


Ладно, еще один пример — вот я пишу свою функцию atoi, которая берет строку и возвращает число:
int atoi (string s);


Такая функция должна возвращать exception или не должна?


Или мне надо сразу писать две функции?:
int atoi (string s) throw exception;

int atoi (string s, int default_value) throw exception
{
  try
  {
    return atoi (s);
  }
  catch (parse_error)
  {
    return default_value;
  }
}


И так на каждую библиотечную функцию?
Re[10]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 17.09.02 06:46
Оценка:
Здравствуйте Sergey Zhulin, Вы писали:

SZ>Вот немного переписаный кусок кода:

SZ>void writeLog( const std::string& strLog )
SZ>{
SZ> try
SZ> {
SZ> File file ("log.dat");
SZ> file.Write (s);
SZ> }
SZ> catch(...)
SZ> {
SZ> // assertion для debug версии.

Ну и нахрена мне в релизе все эти try/catch, если все равно оно не юзается?

ofstream file("log.dat");
file<<s;
assert(file);

Ну чем этот вариант хуже???

[...]
SZ>и не надо. Не для этого они сделаны чтоб их скипали.

Угу. Они для того, чтобы самому создавать проблемы и решать их... Нафиг, нафиг...
Как все запущенно...
Re[10]: эксепшины vs коды возврата
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.09.02 06:50
Оценка:
SZ>Такие примеры ни чего не доказывают. Повторюсь, они лишь показывают, что логика ориентированная на структурное программирование плохо сочетается с механизмом исключений. К тому же система логирования вообще не должна кидать исключения, их надо прятать за фасадом, потому что из-за ошибки при записи лога приложение должно оставаться работоспособным.

Что ты привязался к названию writeLog обзови ее как-нибудь по другому — write_неважные_данные или сделать_не_очень_важную_операцию....


SZ>Вот немного переписаный кусок кода:


То есть ты хочешь сказать, что я на все библиотечные классы кидающие исключения должен писать свои классы, которые исключения не кидают?

Допустим на миг, что функция writeLog — библиотечная, тогда такой вопрос на засыпку — она должна кидать исключение или нет, если нет, то как нам все-таки узнать, что она закончилась не удачно... Ну ладно добавили все-таки возвращающее значение, которое будет сигнализировать об ошибке.

Опять же, а если getDataFileName — библиотечная, то она должно кидать исключение или не должна, если не должна то как мы узнаем об ошибке, если нам это важно?


DG>>p.s. Самое плохое, что ни в одном языке нет даже простейшего способа скипнуть exception...


SZ>и не надо. Не для этого они сделаны чтоб их скипали.


А как писать устойчивые приложения, если не скипать исключения. Обидно, когда вся программа валится из-за того, что не получилось сделать какое-то левое действие.
Re[11]: эксепшины vs коды возврата
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.09.02 06:55
Оценка:
Здравствуйте Vladik, Вы писали:

V>Ну и нахрена мне в релизе все эти try/catch, если все равно оно не юзается?


Кто сказал, что они не юзаются? Они говорят о том, что любая ошибка при записи лога (памяти не хватило, диск отвалился) не повлият на работу программы.


V>ofstream file("log.dat");

V> file<<s;
V> assert(file);

V>Ну чем этот вариант хуже???


Тем, что в общем случае в release он будет валит всю программу (например, если file-у или operator-у << не хватило памяти)
Re[10]: эксепшины vs коды возврата
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.09.02 06:56
Оценка:
Здравствуйте Sergey Zhulin, Вы писали:

SZ>Такие примеры ни чего не доказывают. Повторюсь, они лишь показывают, что логика ориентированная на структурное программирование плохо сочетается с механизмом исключений.


И в каком месте мой пример был ориентирован на структурное программирование?
Re[11]: эксепшины vs коды возврата
От: Юнусов Булат Россия  
Дата: 17.09.02 06:58
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>Ладно, еще один пример — вот я пишу свою функцию atoi, которая берет строку и возвращает число:

DG>
DG>int atoi (string s);
DG>


DG>Такая функция должна возвращать exception или не должна?


Имхо если чего конвертим во что то то лучше кидать (то что в шарпе вся конвертация кидается ексепшенами позволяет при отладке такие штуки отловить почти сразу)

DG>Или мне надо сразу писать две функции?:

DG>
DG>int atoi (string s) throw exception;

DG>int atoi (string s, int default_value) throw exception
DG>{
DG>  try
DG>  {
DG>    return atoi (s);
DG>  }
DG>  catch (parse_error)
DG>  {
DG>    return default_value;
DG>  }
DG>}
DG>


Если потом придется проверять дефолтный код возврата — чем это лучше чем ловить ексепшен от первого варианта я не понимаю.

DG>И так на каждую библиотечную функцию?

не знаю
Re[12]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 17.09.02 07:09
Оценка:
Здравствуйте DarkGray, Вы писали:

V>>Ну и нахрена мне в релизе все эти try/catch, если все равно оно не юзается?

DG>Кто сказал, что они не юзаются?

Пустой catch(...).

DG>Они говорят о том, что любая ошибка при записи лога (памяти не хватило, диск отвалился) не повлият на работу программы.


А оно и так не повлияет на работу. Тихо вернется игнорируемая ошибка и все.

[...]
V>>Ну чем этот вариант хуже???
DG>Тем, что в общем случае в release он будет валит всю программу (например, если file-у или operator-у << не хватило памяти)

Если нехватит памяти это поймается в совершенно другом месте и все будет хорошо (хотя уже вряд-ли А мусора в программе в виде пустых try/catch (либо, еще хуже, врапперов над библиотечными функциями с пустыми try/catch) будет намного меньше.
Как все запущенно...
Re[12]: эксепшины vs коды возврата
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.09.02 07:26
Оценка: 11 (2)
ЮБ>Если потом придется проверять дефолтный код возврата — чем это лучше чем ловить ексепшен от первого варианта я не понимаю.

default значение там не для того, чтобы на него проверять, а для того, чтобы можно было проигнорировать ошибку, если нам это не важно.


Тогда, например, можно писать так:

void put_Value (string s)
{
  this.value = atoi (s, this.value);
 
}

а не так:
void put_Value (string s)
{
  try
  {
    this.value = atoi(s);
  }
  catch (...)
  {
  }
}



Или так:
void Init()
{
  this.value = atoi (LoadString(), 0);
}



Особенно исключения не удобны при функциональном стиле программирования:

маленткая функция:
int MyFunc()
{
  return atoi(GetValueFromFile();
}


Превращаясь в такого вот монстра:
string s;
try
{
  s = GetValueFromFile();
}
catch (...)
{
  try
  {
    s = GetValueFromRegistry();
  }
  catch (...)
  {
    s = GetValueFromUser();
  }
}
return atoi(s);


А хотелось бы что-нибудь такого:
return atoi (or_call(GetValueFromFile(), GetValueFromRegistry(), GetValueFromUser()));


Или так:
  return atoi (GetValueFromFile() ?? GetValueFromRegistry() ?? GetValueFromUser());

Где ?? оператор, который в случае исключение вызывает следующую функцию, иначе возращает значение
Re[21]: Я не вижу проблем с исключениями в конструкторах (-)
От: jazzer Россия Skype: enerjazzer
Дата: 17.09.02 07:39
Оценка:
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[22]: Я не вижу проблем с исключениями в конструкторах (-)
От: Vladik Россия  
Дата: 17.09.02 07:51
Оценка:
Здравствуйте jazzer, Вы писали:


class X
{
public:
    X(){throw 0;}
};

class Y
{
X x;
};


Можно сколько угодно рассуждать о принципиальной невозможности существования Y, если не может существовать агрегируемый X, только на практике это приведет к очередному извращению, типа:


class Y
{
    std::auto_ptr<X> x;
public:
    Y()
    {
        try
        {
            x.reset(new X);
        }
        catch (...)
        {
        }
    }
};
Как все запущенно...
Re[23]: Я не вижу проблем с исключениями в конструкторах
От: jazzer Россия Skype: enerjazzer
Дата: 17.09.02 11:01
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>

V>
V>class X
V>{
V>public:
V>    X(){throw 0;}
V>};

V>class Y
V>{
V>X x;
V>};
V>


V>Можно сколько угодно рассуждать о принципиальной невозможности существования Y, если не может существовать агрегируемый X,


не можно, а нужно.

V> только на практике это приведет к очередному извращению, типа:

V>
V>class Y
V>{
V>    std::auto_ptr<X> x;
V>public:
V>    Y()
V>    {
V>        try
V>        {
V>            x.reset(new X);
V>        }
V>        catch (...)
V>        {
V>        }
V>    }
V>};
V>


Это — только плохой дизайн и не более того.
Если класс Х предполагается использовать даже в том случае, если он не смог инициализироваться (что слегка абсурдно, но в реальных задачах и не такое встречается) — например, использовать какое-то дефолтное значение, то класс и должен быть спроектирован именно так.
Вы приводите примеры из трех строчек, оторванные от жизни.
Приведите реальный пример такой пары классов, какую Вы описали, и тогда можно будт говорить предметно.
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[24]: Я не вижу проблем с исключениями в конструкторах
От: Vladik Россия  
Дата: 17.09.02 11:20
Оценка:
Здравствуйте jazzer, Вы писали:

J>Это — только плохой дизайн и не более того.


Ну вот, опять уперлись в "правильное проектирование". Может ты мне тогда поверишь, что можно так "правильно спроектировать", что никакой нужды в исключениях (и, тем более в конструкторах), просто не будет?

[...]
J>Приведите реальный пример такой пары классов, какую Вы описали, и тогда можно будт говорить предметно.

Реальные примеры уже приводились. Никакой очевидной пользы от эксепшинов, кроме варианта с "кучей вызовов и одним местом вываливания" при ошибке хотя бы одного из вызовов я не увидел. Для таких случаев я тоже использую механизм исключений (это было описано в моей первой мессаге).
Как все запущенно...
Re[23]: Я не вижу проблем с исключениями в конструкторах (-)
От: Аноним  
Дата: 17.09.02 12:22
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>
V>class Y
V>{
V>    std::auto_ptr<X> x;
V>public:
V>    Y()
V>    {
V>        try
V>        {
V>            x.reset(new X);
V>        }
V>        catch (...)
V>        {
V>        }
V>    }
V>};
V>


class Y
{
    std::auto_ptr<X> x;
public:
    Y() :
        x(new(nothrow) X)
    {
    }
};
Re[13]: эксепшины vs коды возврата
От: Vladik Россия  
Дата: 17.09.02 13:08
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>Или так:

DG>
DG>  return atoi (GetValueFromFile() ?? GetValueFromRegistry() ?? GetValueFromUser());
DG>

DG>Где ?? оператор, который в случае исключение вызывает следующую функцию, иначе возращает значение

Кстати как вариант, ввести некоторые синтаксические конструкции для нормальной работы с исключениями, помимо уродских try/catch. Тогда все не так печально будет...
Как все запущенно...
Re[24]: Я не вижу проблем с исключениями в конструкторах (-)
От: jazzer Россия Skype: enerjazzer
Дата: 17.09.02 13:52
Оценка:
Здравствуйте Аноним, Вы писали:

А>
А>class Y
А>{
А>    std::auto_ptr<X> x;
А>public:
А>    Y() :
А>        x(new(nothrow) X)
А>    {
А>    }
А>};
А>


Погодите, new(nothrow) означает, что оператор new не выбросит своего исключения, это не означает, что при такой записи не будет пропущено исключение, выброшенное конструктором Х.
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[25]: Как не верти, мы упремся в правильное проектирование
От: jazzer Россия Skype: enerjazzer
Дата: 17.09.02 14:06
Оценка: 6 (1)
Потому что правильное проектирование в первую очередь означает применение соответствующих средств языка в подходящих для этого ситуациях.

Если я правильно понимаю, Вы говорите: "Обычно эксепшены используются по-дурацки, и такой код выглядит маразматичным" (пример с SomeValue — лучшее тому доказательство).

Я с Вами соглашусь: если средство используется не в тех условиях, для которых оно предназначено, то код выглядит либо извращением, либо глупостью.

Только это не свойство исключений, это свойство любых средств: наследования, виртуальных функций, шаблонов и т.п.

Например, мне приходилось видеть код вида

f()
{
  preparing_to_print();
  before_print();
  about_to_print();
  pre_print();
  print();
  post_print();
  after_print();
}


Где все вызовы виртуальны. Шикарный пример мощи ООП.


Любую идею можно опускать, показывая всем маразматичный код, использующий эту идею.
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[26]: Как не верти, мы упремся в правильное проектирование
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.09.02 14:14
Оценка:
Здравствуйте jazzer, Вы писали:

J>Потому что правильное проектирование в первую очередь означает применение соответствующих средств языка в подходящих для этого ситуациях.


J>Если я правильно понимаю, Вы говорите: "Обычно эксепшены используются по-дурацки, и такой код выглядит маразматичным" (пример с SomeValue — лучшее тому доказательство).



Я, например, хочу сказать, не то что исключения — плохо, а то что они не доведены до конца.

Как уже было выше показано, для получения информации об ошибке
1. В части случаев удобно возвращаемое значение
2. В части случаев удобно исключение

C++ позволяет легко перейти от возвращаемого значение к исключению, но обратный переход выливается в безобразного монстра — вот именно это мне и не нравится.
Re[27]: Согласен
От: jazzer Россия Skype: enerjazzer
Дата: 17.09.02 15:21
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>

DG>Я, например, хочу сказать, не то что исключения — плохо, а то что они не доведены до конца.

DG>Как уже было выше показано, для получения информации об ошибке

DG>1. В части случаев удобно возвращаемое значение
DG>2. В части случаев удобно исключение

DG>C++ позволяет легко перейти от возвращаемого значение к исключению, но обратный переход выливается в безобразного монстра — вот именно это мне и не нравится.


Мне мое использование исключений очень нравится :), но оно у меня происходило именно по первому сценарию:
я использовал разные библиотеки, основанные на кодах возврата и оборачивал их в исключения так, как мне представлялось логичным для моей задачи.



По сути (не знаю, кто еще разделит мою точку зрения), исключения являются частью public-интерфейса библиотеки/модуля, и эти исключения должны быть проработаны так же тщательно, как и интерфейс вызовов, и определяться, какие исключения данная библиотека будет выбрасывать, необходимо также на этапе проектирования.

Соответственно, хорошему разработчику неплохо бы не пренебрегать, например, возможностью объявлять функции, одновременно объявляя, какие исключения они могут выкинуть.

И, к сожалению, я очень мало видел такого кода.
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[28]: Согласен
От: WeCom Беларусь  
Дата: 18.09.02 06:00
Оценка:
Здравствуйте jazzer, Вы писали:

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


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

Напиример (все упрощенно, только чтобы донести суть), в "старой" библиотеке есть функция:

void writeLogС(char* msg);


Если же мы пишем обертку на С++, то очевидно наша функция будет выглядеть так:

void writeLogСPP(const char* msg);

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

Так?

{
  writeLogC(const_cast<char*>(msg));
}


Или как-то так так (без обработки ошибок и учета исключений)?

{
  char *tmp_buf = new char[strlen(msg)+1];
  strcpy(tmp_buf,msg);
  writeLogC(tmp_buf);
}


Ясно, что второй вариант надежнее, но сколько в итоге будет непроизводительных затрат? Вот и пишем первый вариант в надежде на здравый смысл разработчика writeLogC и на истиность его (документации) заререний о том, что его функция по указателю ничего не пишет.
С исключениями совершенно аналогично. Мы используем функции без спецификации их исключений и надеемся на то, что эти функции будут вести себя так, как если бы эта спецификация была указана. Как только же мы перестаем верить честному слову разработчиков функции (пытаемся написать действительно надежную программу), мы вынуждены писать слишком много try-catch, так как формально функция _может_ выкинуть любое исключение. Вот в этом то и состоит суть проблемы с использованием исключений в C++, IMNSHO.
Re[29]: Согласен
От: Vladik Россия  
Дата: 18.09.02 06:42
Оценка:
Здравствуйте WeCom, Вы писали:

WC>Вот! Наконец-то дошли до сути проблемы.

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

Об этой проблеме я тоже упоминал в одном из "пунктов".

WC>А раз не указано, то получается, что могут быть выброшены любые исключения и предусматривать их обработку действительно очень муторно. Аналогичная проблема существует и с const. (автору топика) не желаешь ли и спецификатор const раскритиковать ровно с тех же позиций?


Я чего-то не уловил связи... В смысле критиковать отсутствие const там где он должен быть, конечно, нужно (неужели кто-то будет спорить?). Кстати, с каких пор в сях отменили const?

WC>Напиример (все упрощенно, только чтобы донести суть), в "старой" библиотеке есть функция:

WC>
WC>void writeLogС(char* msg);
WC>

WC>Если же мы пишем обертку на С++, то очевидно наша функция будет выглядеть так:
WC>
WC>void writeLogСPP(const char* msg);
WC>


Уж и не знаю насколько очевидно, кто-то предпочтет:
void writeLogСPP(const std::string &msg);
Как все запущенно...
Re[29]: Согласен
От: Bell Россия  
Дата: 18.09.02 07:53
Оценка:
Здравствуйте WeCom, Вы писали:

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


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


WC>Вот! Наконец-то дошли до сути проблемы.

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

Эээ батенька. Посмотрите-ка пункт 15.4 стандарта.

Конечно не все компиляторы это дело поддерживают, но все равно это не дает оснований для столь категоричных заявлений.
Любите книгу — источник знаний (с) М.Горький
Re[30]: Согласен
От: Vladik Россия  
Дата: 18.09.02 08:33
Оценка:
Здравствуйте Bell, Вы писали:

WC>>Вот! Наконец-то дошли до сути проблемы.

WC>>Ведь основные неудобства и сложности использования (реагирования на) исключения как раз в том, что в функциях (методах) нет указаний какие исключения они могут выбрасывать.
B>Эээ батенька. Посмотрите-ка пункт 15.4 стандарта.

Расскажи это, например, борланду. Ни одного throw в объявлении функций я там не заметил.
Как все запущенно...
Re[30]: Согласен
От: WeCom Беларусь  
Дата: 18.09.02 09:13
Оценка:
Здравствуйте Bell, Вы писали:

B>Эээ батенька. Посмотрите-ка пункт 15.4 стандарта.


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


Я наверное недостаточно точно выразил свою мысль. Стандарт (и компиляторы) дают возможность указывать возможные исключения. Это я прекрасно знаю. НО, в РЕАЛЬНОСТИ (это важно и это я имел в виду) очень и очень мало кто этим пользуется в полной мере, отсюда и проблемы. Точно такие же как и с квалификатором const.
Re[31]: Согласен
От: Bell Россия  
Дата: 18.09.02 09:16
Оценка:
Здравствуйте Vladik, Вы писали:

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


WC>>>Вот! Наконец-то дошли до сути проблемы.

WC>>>Ведь основные неудобства и сложности использования (реагирования на) исключения как раз в том, что в функциях (методах) нет указаний какие исключения они могут выбрасывать.
B>>Эээ батенька. Посмотрите-ка пункт 15.4 стандарта.

V>Расскажи это, например, борланду. Ни одного throw в объявлении функций я там не заметил.


Я ведь сказал, что не все компиляторы соответствуют данному требованию стандарта
Если на то пошло, то MSVC6 тоже это не поддерживает
Любите книгу — источник знаний (с) М.Горький
Re[32]: Согласен
От: Vladik Россия  
Дата: 18.09.02 09:25
Оценка:
Здравствуйте Bell, Вы писали:

V>>Расскажи это, например, борланду. Ни одного throw в объявлении функций я там не заметил.

B>Я ведь сказал, что не все компиляторы соответствуют данному требованию стандарта

Да, но даже если компилятор поддерживает это, он не обязует разработчика соответствующим образом объявлять функции.

B>Если на то пошло, то MSVC6 тоже это не поддерживает


В смысле не поддерживает??? А я вовсю использовал такую декларацию Да и в MSDN'е тоже встречаются правильные прототипы.
Как все запущенно...
Re[33]: Согласен
От: Sergey Россия  
Дата: 18.09.02 09:36
Оценка: 8 (1)
Здравствуйте Vladik, Вы писали:

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


V>>>Расскажи это, например, борланду. Ни одного throw в объявлении функций я там не заметил.

B>>Я ведь сказал, что не все компиляторы соответствуют данному требованию стандарта

V>Да, но даже если компилятор поддерживает это, он не обязует разработчика соответствующим образом объявлять функции.


B>>Если на то пошло, то MSVC6 тоже это не поддерживает


V>В смысле не поддерживает??? А я вовсю использовал такую декларацию Да и в MSDN'е тоже встречаются правильные прототипы.


Поддерживает — означает, что если из функции, для которой специфицирован тип исключений, вылезло исключение неподходящего типа, то вызывается функция unexpected(). MSVC этого не делает, о чем и сообщается в документации, и при компиляции. Compiler Warning (level 3) C4290 : "C++ Exception Specification ignored".
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[33]: Согласен
От: Bell Россия  
Дата: 18.09.02 10:02
Оценка:
Здравствуйте Vladik, Вы писали:

V>Да, но даже если компилятор поддерживает это, он не обязует разработчика соответствующим образом объявлять функции.

Да, С++ часто не обязывает разработчика делать что-либо.

B>>Если на то пошло, то MSVC6 тоже это не поддерживает


V>В смысле не поддерживает??? А я вовсю использовал такую декларацию Да и в MSDN'е тоже встречаются правильные прототипы.

Ну вот прям в этом смысле и не поддерживает:

Note   Microsoft C++ does not support exception-specifications, as described in section 15.4 of the ANSI C++ draft. In addition, it does not support function-try-block described in section 15 of the ANSI C++ draft.
Любите книгу — источник знаний (с) М.Горький
Re[34]: Согласен
От: Vladik Россия  
Дата: 18.09.02 10:22
Оценка:
Здравствуйте Bell, Вы писали:

V>>Да, но даже если компилятор поддерживает это, он не обязует разработчика соответствующим образом объявлять функции.

B>Да, С++ часто не обязывает разработчика делать что-либо.

ИМХО это не тот случай, когда это хоть чем-то оправдано. С одной стороны ввели специальное объявление для функций, кидающих эксепшины, с другой — оставили это полностью на совесть разработчику. С const ситуация все же несколько иная, — да, тоже можно все испортить, но компилятор хотя бы попытается предупредить. С эксепшинами, конечно, это сделать компилятору намного сложнее (это тоже обсуждали в другом топике), точнее даже невозможно при существующем положении дел. Но хотя бы с некоторыми ограничениями было бы желательно...
Как все запущенно...
Re[35]: Согласен
От: jazzer Россия Skype: enerjazzer
Дата: 18.09.02 13:01
Оценка:
Здравствуйте Vladik, Вы писали:

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


V>>>Да, но даже если компилятор поддерживает это, он не обязует разработчика соответствующим образом объявлять функции.

B>>Да, С++ часто не обязывает разработчика делать что-либо.

V>ИМХО это не тот случай, когда это хоть чем-то оправдано. С одной стороны ввели специальное объявление для функций, кидающих эксепшины, с другой — оставили это полностью на совесть разработчику. С const ситуация все же несколько иная, — да, тоже можно все испортить, но компилятор хотя бы попытается предупредить. С эксепшинами, конечно, это сделать компилятору намного сложнее (это тоже обсуждали в другом топике), точнее даже невозможно при существующем положении дел. Но хотя бы с некоторыми ограничениями было бы желательно... :(



Все совершенно правильно сделали. Точно так же, как и с const.
Ты можешь в своих программах вообще забить на const и передавать все про неконстантным ссылкам и объектам, а для контроля того, что функция, которой ты передал неконстантную ссылку, объект не изменила, использовать контрольную сумму. После чего останется написать код с такими вызовами, после каждого вызова вставить проверки контрольной суммы и показывать всем как образец маразматичного кода :)

Та же ситуация и с исключениями.
Я, например, не очень понимаю, почему в STL (в Стандарте!) функции, по сути своей не выбрасывающие исключений (типа size()), не объявлены явно с throw(), в то время как, по-моему, версия STL от RogueWave эти спецификации имеет (и они отключаются соответствующим дефайном, если компилятор не поддерживает синтаксис).


В общем, давайте возьмемся за руки и все вместе пообещаем друг другу писать у своих функций exception specifications! (Хотя бы при помощи дефайнов :) )
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[36]: Исключения и шаблоны
От: Anton V. Kolotaev  
Дата: 18.09.02 14:31
Оценка:
Здравствуйте jazzer, Вы писали:

J>В общем, давайте возьмемся за руки и все вместе пообещаем друг другу писать у своих функций exception specifications! (Хотя бы при помощи дефайнов )


Это, конечно, замечательно. А если все на шаблонах сидит?

template <class T>
int f()  // вот что здесь прописать???
{
    return T::f(); // неизвестно, какие исключения f может кидать. 
                   // мы должны пропустить их все или часть
}


Так что, в бесшаблонном коде спецификация исключений — благо, а в шаблонном — неясно, что делать.
Re[37]: Исключения и шаблоны
От: jazzer Россия Skype: enerjazzer
Дата: 19.09.02 07:48
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

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


J>>В общем, давайте возьмемся за руки и все вместе пообещаем друг другу писать у своих функций exception specifications! (Хотя бы при помощи дефайнов )


AVK>Это, конечно, замечательно. А если все на шаблонах сидит?


AVK>
AVK>template <class T>
AVK>int f()  // вот что здесь прописать???
AVK>{
AVK>    return T::f(); // неизвестно, какие исключения f может кидать. 
AVK>                   // мы должны пропустить их все или часть
AVK>}
AVK>


AVK>Так что, в бесшаблонном коде спецификация исключений — благо, а в шаблонном — неясно, что делать.



Боюсь, что тут не просто неясно, что делать, а просто нечего делать
Ведь так как спецификация исключений не является частью типа функции, для шаблона она не будет видна ни при каком раскладе, просто в синтаксисе С++ нет соответствующего механизма.

Видимо, остается делать то же, что мы делаем, когда пишем шаблон для классов, которые должны выполнять некий протокол, непроверяемый компилятором — т.е. верить на слово.

Например, если T::f() — это size или что-то в этом роде, не должное по сути своей выбрасывать никаких исключений, то мы имеем полное право объявлить нашу шаблонную функцию как не выбрасывающую исключений.
Или это, например, — файловый класс, который может выбрасывать исключения только из соответствующего дерева классов исключений, тогда корень этого дерева можно передавать в качестве параметра шаблона (как это происходит в STL с их многочисленными внутренними typedef-ами), например:

template <class File, class FileException = File::exception_type>
int f() throw (FileException)
{
...
};


Это — один способ.

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


А вообще, тема очень интересна и заслуживает отдельного топика.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.