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 может кидать. 
                   // мы должны пропустить их все или часть
}


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