Re[18]: Checked exceptions... зло или добро?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.07.05 12:38
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>eao197 wrote:


>> C>Это я про "throw()" — обозначение того, что функция не будет кидать

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

C>Вообще-то, по пункту 15.4.4 компилятор должен ругаться на такое.


C>VC++ выводит предупреждение в этом случае.


Берем пример:
class    E {};

void f() throw( E )
{
    throw E();
}

void a() throw()
{
    f();
}


Компилируем cl -c -GX:
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

throw.cpp


Предупреждений нет.
Пробуем cl -c -GX -W4:
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

throw.cpp
throw.cpp(3) : warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)


Берем g++ v.3.3.3 (cygwin), g++ -c. Никаких сообщений.

Берем Borland C++ 5.6, bcc32 -c -w. Никаких сообщений.

Берем Digital Mars C++ 8.35n, dmc -c -Ae. Никаких сообщений.

Берем Comeau Online:
Thank you for testing your code with Comeau C/C++!
Tell others about http://www.comeaucomputing.com/tryitout ! 

Your Comeau C/C++ test results are as follows: 

Comeau C/C++ 4.3.3 (Aug  6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing.  All rights reserved.
MODE:strict errors C++

In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link).


Может там где-то ключики какие-то специальные есть?

>> Все, что делает throw(), это, образно говоря:

>>
>>try
>> {
>> <какой-то код>
>> }
>>catch( ... )
>> {
>> unexpected(); // Т.е. throw bad_exception();
>> }
>>
>>
C>Это как бы и есть гарантия того, что мой код не получит исключением в лоб.

Он его получит по лбу
Все равно возникнет bad_exception там, где вообще исключений не ждут.

>> Причем, кажется в boost и в mozilla, я встречал достаточно понятные и

>> разумные обоснования по поводу того, что throw(), как и
>> throw(something) лучше не использовать.

C>Да, так как некоторые тупые компиляторы действительно генерируют такой

C>код во всех throw()-функциях. На нормальных компиляторах — можно.

Проблема с тем, что иногда приходится переходить на ненормальные компиляторы.

>>>> А зачем он в Java? Указать что и unchecked exeptions не проходят? Дык,

>>>> а толку то. Может в C#-пе будет полезен.
>> C>В Яве/C# исключение может вылететь в любой момент (какой-нибудь
>> C>OutOfMemory), а в С++ можно гарантировать, что функции не кинут
>> исключения.
>> Это как?

C>По JLS (Java Language Specification) исключение может вылететь в любой

C>момент (наприме, VirtualMachineError).

Мне интересно, как в C++ можно гарантировать, что функция не кинет исключения?
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: Checked exceptions... зло или добро?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.07.05 12:45
Оценка:
Здравствуйте, mishaa, Вы писали:

M>Есть интересно какие-нибудь Exception usage patterns ну или Style guidelines?


Например: http://www.boost.org/more/generic_exception_safety.html
У Страуструпа в специальном издании "Язык программирования C++" есть отдельное приложение, касающееся безопасности исключений.
У Саттера в "Решении сложных задач на C++" целая глава посвящена написанию безопасного по отношению к исключениям кода. В этой главе, имхо, главной нитью идет мысль, что исключения -- это единственный способ дать знать об ошибке в конструкторе.

А вообще, недавно перечитал об исключениях у Страуструпа и Саттера и пришел к мнению, что лучше три раза подумать, прежде чем throw написать.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[10]: Checked exceptions... зло или добро?
От: Павел Кузнецов  
Дата: 18.07.05 13:11
Оценка:
Cyberax,

C> Однако справедливые возражения того же Гослинга или Гриффита

C> (http://octopull.demon.co.uk/java/ExceptionalJava.html) почему-то не
C> находятся сразу же.

Гм... Эту ссылку я приводил, там не возражения, а как раз рекомендация не налегать
на checked exceptions...

C> Причем несложно заметить, что основные возражения о exception'ах идут от

C> любителей динамических языков, с их идеологией "нафиг нам системы
C> безопасности не нужны — у нас есть юнит-тесты".

Это Bruce Eckel. Остальные приводят достаточно внятную аргументацию, основным положением
которой является то, что checked exceptions мешают основной идее исключений: изоляции
промежуточных уровней от знания об исключительных ситуациях, возникающих на нижних.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[19]: Checked exceptions... зло или добро?
От: Cyberax Марс  
Дата: 18.07.05 13:14
Оценка:
eao197 wrote:

> C>Вообще-то, по пункту 15.4.4 компилятор должен ругаться на такое.

> C>VC++ выводит предупреждение в этом случае.
> Компилируем cl -c -GX:
>
>Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
>Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
>throw.cpp
>
> Берем g++ v.3.3.3 (cygwin), g++ -c. Никаких сообщений.

Вот gcc как раз выдает варнинги (про Комо — не знаю), какой-то ключ
нужен. Приду домой — посмотрю...

> C>Это как бы и есть гарантия того, что мой код не получит исключением

> в лоб.
> Он его получит по лбу
> Все равно возникнет bad_exception там, где вообще исключений не ждут.

bad_exception — это уже полный кранты, аналог access violation.

> C>Да, так как некоторые тупые компиляторы действительно генерируют такой

> C>код во всех throw()-функциях. На нормальных компиляторах — можно.
> Проблема с тем, что иногда приходится переходить на ненормальные
> компиляторы.

Для этого и прдумали макросы THROW() и никаких проблем.

> C>По JLS (Java Language Specification) исключение может вылететь в любой

> C>момент (наприме, VirtualMachineError).
> Мне интересно, как в C++ можно гарантировать, что функция не кинет
> исключения?

С-шные функции исключения не кидают, они кидаются только в С++ных
функциях. Ну а вклеить в mangled-name информацию о том, что функция
кидает (или не кидает) исключения — не так уж сложно.

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[11]: Checked exceptions... зло или добро?
От: Павел Кузнецов  
Дата: 18.07.05 13:20
Оценка:
eao197,

e> А в C++, напротив, нельзя понять, функция:

e>
 e> void f();
 e>

e> будет генерировать исключения или нет.

Вопрос такой: а как компилятор должен был бы использовать спецификацию исключений,
подразумеваемую тобой?
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[12]: Checked exceptions... зло или добро?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.07.05 13:34
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>eao197,


e>> А в C++, напротив, нельзя понять, функция:

e>>
 e>> void f();
 e>>

e>> будет генерировать исключения или нет.

ПК>Вопрос такой: а как компилятор должен был бы использовать спецификацию исключений,

ПК>подразумеваемую тобой?

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

Хотелось бы иметь какой-то спецификатор, скажем nothrow, который указывал бы компилятору, что данная функция не намерена сама порождать исключения. И при этом чтобы компилятор не строил вокруг фунции обертку из try/catch вообще. А только использовал эту спецификацию для выдачи предупреждений. Т.е.:
void f();
void h() throw( std::exception );

void g() nothrow
    {
        f();
        
        try
            {
                h();
            }
        catch( const std::exception & x )
            {
            }
    }


выдал бы предупреждение о том, что в g() вызов функции f() может привести к возникновению исключения.

Только и здесь не все так ладно. Этоже получается, что любое обращение к new или STL уже не даст написать nothrow (или придется везде try/catch лепить).

В общем, не знаю я. Знаю только, что несколько раз получал в деструкторе исключение от функции, которая была не мной написана. И я вообще не знал, что в ней исключения могут генерироваться -- благо исходники были. Вот хотелось бы получить от компилятора в этом плане какую-нибудь помошь. Но вот как?
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[18]: Checked exceptions... зло или добро?
От: Павел Кузнецов  
Дата: 18.07.05 13:42
Оценка: 1 (1)
Cyberax,

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

C> Вообще-то, по пункту 15.4.4 компилятор должен ругаться на такое.


Гм... 15.4/4 говорит о присваивании указателей на функции, имеющих
exception specification...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[17]: Checked exceptions... зло или добро?
От: Павел Кузнецов  
Дата: 18.07.05 13:50
Оценка:
eao197,

e> порождать исключения). Все, что делает throw(), это, образно говоря:

e>
 try
 e>  {
 e>   <какой-то код>
 e>  }
 e> catch( ... )
 e>  {
 e>   unexpected(); // Т.е. throw bad_exception();
 e>  }
 e>


Только по умолчанию не "т.е. throw bad_exception()", а "call std::terminate()" (18.6.2.2), т.е. abort() (18.6.3.1).

e> Причем, кажется в boost и в mozilla, я встречал достаточно понятные и

e> разумные обоснования по поводу того, что throw(), как и throw(something)
e> лучше не использовать.

Да, лучше спецификацию исключений вообще не использовать. Если бы она была определена
несколько иным образом, то тогда хотя бы использование throw() имело бы смысл. Пока неясно, решится
ли комитет на эти изменения, но обсуждения их возможности ведутся...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[19]: Checked exceptions... зло или добро?
От: Павел Кузнецов  
Дата: 18.07.05 13:55
Оценка:
eao197,

e> Мне интересно, как в C++ можно гарантировать, что функция не кинет исключения?


Спецификация throw() подходит к этому ближе всего: в случае исключения исполнение программы будет прервано.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[20]: Checked exceptions... зло или добро?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.07.05 14:03
Оценка: +2 :))
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>eao197,


e>> Мне интересно, как в C++ можно гарантировать, что функция не кинет исключения?


ПК>Спецификация throw() подходит к этому ближе всего: в случае исключения исполнение программы будет прервано.


Согласен.
Однако, напоминает гарантированность отсутствия перхоти путем насильственного отсечения головы от тулувища при обнаружении перхоти
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[18]: Checked exceptions... зло или добро?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.07.05 14:03
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>eao197,


e>> порождать исключения). Все, что делает throw(), это, образно говоря:

e>>
 try
 e>>  {
 e>>   <какой-то код>
 e>>  }
 e>> catch( ... )
 e>>  {
 e>>   unexpected(); // Т.е. throw bad_exception();
 e>>  }
 e>>


ПК>Только по умолчанию не "т.е. throw bad_exception()", а "call std::terminate()" (18.6.2.2), т.е. abort() (18.6.3.1).


В том-то и дело, что по умолчанию происходит вызов std::terminate. Если же установить собственный unexpected, то вполне можно генерить bad_exception. Все же bad_exception производна от std::exception и это дает возможность где-то на верхнем уровне приложения что-то сделать или перезапуститься. А вот c terminate такого увы...
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[19]: Checked exceptions... зло или добро?
От: Павел Кузнецов  
Дата: 18.07.05 14:28
Оценка: 1 (1)
eao197,

ПК>> Только по умолчанию не "т.е. throw bad_exception()", а "call

ПК>> std::terminate()" (18.6.2.2), т.е. abort() (18.6.3.1).

e> В том-то и дело, что по умолчанию происходит вызов std::terminate. Если

e> же установить собственный unexpected, то вполне можно генерить
e> bad_exception. Все же bad_exception производна от std::exception и это
e> дает возможность где-то на верхнем уровне приложения что-то сделать или
e> перезапуститься. А вот c terminate такого увы...

Имхо, попытки генерировать std::bad_exception в std::unexpected для случая throw() сродни попыткам
бросать исключения в случае нарушения предусловий вместо завершения программы. И то, и другое
(за исключением редких случаев) свидетельствует об ошибке в программе, и попытки восстановления
в подавляющем большинстве подобных случаев смысла не имеют. Напротив, лучшее, что можно сделать --
прервать исполнение прямо в точке, где продиагностирована (логическая) ошибка, без раскрутки стека,
с тем, чтоб был сгенерирован дамп/снимок стека, позволяющий программисту разобраться в том, что
происходило. А пытаться продолжать исполнение -- серьезно рисковать данными пользователя.

По этому поводу есть неплохое обсуждение в comp.lang.c++.moderated:
http://groups-beta.google.com/group/comp.lang.c++.moderated/browse_frm/thread/80083ac31a1188da/c40035067fafc0e8
для начала можно
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[20]: Checked exceptions... зло или добро?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.07.05 14:35
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Имхо, попытки генерировать std::bad_exception в std::unexpected для случая throw() сродни попыткам

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

ПК>По этому поводу есть неплохое обсуждение в comp.lang.c++.moderated:

ПК>http://groups-beta.google.com/group/comp.lang.c++.moderated/browse_frm/thread/80083ac31a1188da/c40035067fafc0e8
ПК>для начала можно

За ссылку спасибо. Найду время -- прочитаю.

Да и с твоим мнением я, в принципе, согласен. Я после прочтения третьего издания Страуструпа поигрался немного со спецификациями исключений и решил, что лучше с ними не связываться. Особенно с throw(). Иногда использовал throw(std::exception) чтобы показать, что я сам в этих функциях генерирую исключения, но потом и от этого отказался.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[21]: Checked exceptions... зло или добро?
От: Павел Кузнецов  
Дата: 18.07.05 14:44
Оценка:
eao197,

e> издания Страуструпа поигрался немного со спецификациями исключений и

e> решил, что лучше с ними не связываться. Особенно с throw(). Иногда
e> использовал throw(std::exception) чтобы показать, что я сам в этих
e> функциях генерирую исключения, но потом и от этого отказался.

Мне вполне нравится, когда спецификации исключений указаны. Но не в коде, а в комментариях.
void f(); // throw()
void g(); // throw(MyException)

Плюс, пустая спецификация (throw()) еще может оказаться полезной некоторым компиляторам (vc, gcc...) для
оптимизации. Периодически для последнего вводят какое-нибудь расширение. Также не менее полезным
оказывается антоним -- спецификация, указывающая, что функция не возвращает управление.
template< class E >
void throw_(); // always throws E

Соответственно, для этих случаев можно завести макросы, от которых, кроме комментирования, еще
и польза будет:
void f() NOTHROW;

template< class E >
void throw_() NORETURN;
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[22]: Checked exceptions... зло или добро?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.07.05 14:55
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Соответственно, для этих случаев можно завести макросы, от которых, кроме комментирования, еще

ПК>и польза будет:
ПК>
ПК>void f() NOTHROW;

ПК>template< class E >
ПК>void throw_() NORETURN;
ПК>


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

Да и введение макроса NOTHROW будет означать, что при переходе с компилятора на компилятор я (или тот, кто будет сопровождать код после меня) должен буду помнить про правильную адаптацию NOTHROW к новому компилятору. Это все решаемо, но напрягает.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[23]: Checked exceptions... зло или добро?
От: Павел Кузнецов  
Дата: 18.07.05 15:10
Оценка: +1
eao197,

e> Да и введение макроса NOTHROW будет означать, что при переходе с

e> компилятора на компилятор я (или тот, кто будет сопровождать код после
e> меня) должен буду помнить про правильную адаптацию NOTHROW к новому
e> компилятору. Это все решаемо, но напрягает.

Безусловно, поддержка стандартом этих вещей была бы очень полезной. Надеюсь, что-нибудь в следующей
версии спецификации C++ по этому поводу появится...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[11]: Checked exceptions... зло или добро?
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.07.05 17:13
Оценка: +2
Здравствуйте, eao197, Вы писали:

E>будет генерировать исключения или нет. Конечно, можно перестраховаться и все неизвестные функции в try/catch обрамлять (особенно в деструкторах). Но ведь это overhead не слабый получается.


А зачем обрамлять то? Пропускай их и все. Если появится код которому по его логие потребуется обработать исключение, то он и будет знать что и как обрабатывать. А обрабатывать на всякий пожарный — это маразм.
... << RSDN@Home 1.2.0 alpha rev. 578>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Checked exceptions... зло или добро?
От: pvgoran Россия  
Дата: 18.07.05 17:25
Оценка:
Здравствуйте, eao197, Вы писали:

E>Мне интересно, как в C++ можно гарантировать, что функция не кинет исключения?


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

Например, таковы AFAIK реализации std::swap<> для STL-контейнеров.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[6]: Движутся ли mainstream языки в сторону лиспа?
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.07.05 17:57
Оценка: 5 (1)
Здравствуйте, mishaa, Вы писали:

M>Хм.. если инстументом не пользуются может он неудобный?


В чем разница при использовании между исключениями Явы и Шарпа?

M>А вот я посмотрел на реализацю Apache Ant


M>org.apache.tools.ant — 1042 (5585Кб) — неужто мало.


M>P.S. Если интересует, то считал я так:

M>
     find . -exec grep " try {" \{\}\; | wc -l


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

Исключение — это не шататная ситуация (об этом и название говорит). Это способ избавиться от их обработки, а не средство увеличения возни с ними. Обрабатывать исключение нужно только если по другому никак. Тогда и проблем с ними не будет. А вот Явовские чекед-исключения приводят к необходимости или описывать все исключения, или обрабатывать их. Народ чтобы не иметь проблем просто перехватывает все подряд. Отсюда и количество.

По мне так в десктоп приложениях стандартным паттерном обработки исключения является перехват исключений где-то не подолеку от цикла обработки сообщений ОС. Тогда при проблемх будет обламываться одна команда инициированная пользователем. А приложение будет продолжать работать. Остальные места — это уже обход явно возникших проблем. И нужно максимально сокращать такие места.
... << RSDN@Home 1.2.0 alpha rev. 578>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Движутся ли mainstream языки в сторону лиспа?
От: pvgoran Россия  
Дата: 18.07.05 18:02
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Cyberax,


C>> Явная спецификация исключений — это, ИМХО, большой плюс.


ПК>Как я понимаю, вопрос достаточно спорный... Это без труда обнаруживается простым запросом

ПК>java checked exceptions, даже не содержащим ничего кроме самого
ПК>термина:

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

IM(very)HO checked exceptions лучше рассматривать как альтернативный механизм возврата значений из функции — и использовать соответствующим образом.
... << RSDN@Home 1.1.4 stable rev. 510>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.