Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Предпочтение исключению, свое или стандартное? 
V
    Опции темы
Dray
Дата 5.7.2006, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Материалист
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 7.10.2003
Где: г. Всеволожск

Репутация: 2
Всего: 6



Например у меня есть класс в котором хранятся числа в каком-то диапазоне. И в случае если кто-то попытается записать число вне диапазона, я хочу кинуть исключение. Как обычно принято делать: создать свой класс-исключение или кидать какое-нибудь стандартное, например out_of_range? 


--------------------
忍者

user posted image
PM MAIL   Вверх
Xenon
Дата 5.7.2006, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Dray, ну ты можешь просто кинуть исключение throw "Error", можешь не создавать класс. Но если тебе ничего не нужно, кроме надписи "Error", то класс не создавай. Если же нужно передать нечто большее, тогда создавай класс. 
PS. Блин, бред написал - исправляю 

Это сообщение отредактировал(а) XenonSk - 5.7.2006, 20:39


--------------------
user posted image  
PM MAIL   Вверх
En_t_end
Дата 5.7.2006, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Dray
Если хочешь мнение, то я бы не стал возвращать в твоем случае false, 0, NULL, минимум - вернул бы enum ErrType{...}; Исключение вообще не стал бы кидать. Просто заведи в классе тот же enum ErrType{NO_ERROR=0,OUT_OF_RANGE=-100}; В каждом методе возьми за привычку(если это не void) возвращать ErrType и получишь практически "бесплатный" расширяемый класс(можешь кроме OUT_OF_RANGE и ещё что-нибудь добавить). Ибо исключение - это всё же дорогое удовольствие, может так получиться, что некий(знаю парочку  smile ) компилятор их не держит и тогда придется адаптировать, кроить, перепроектировать... не только код метода, но и код юзающий метод.

Добавлено @ 18:53 
Кстати, кто-нибуль тестировал на скорость обработку(+перхват) исключения и сравнивания значений двух переменных ? Что-то мне подсказывает, что второе явно быстрее.   

Это сообщение отредактировал(а) En_t_end - 5.7.2006, 18:54
PM MAIL ICQ Skype GTalk Jabber   Вверх
Void
Дата 5.7.2006, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



En_t_end, с таким подходом проще всего писать все на чистом Си (спасибо, что не на ассемблере).

Цитата(En_t_end @  5.7.2006,  20:48 Найти цитируемый пост)
Кстати, кто-нибуль тестировал на скорость обработку(+перхват) исключения и сравнивания значений двух переменных ? Что-то мне подсказывает, что второе явно быстрее.   

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


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
En_t_end
Дата 5.7.2006, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Void
Цитата(Void @  5.7.2006,  23:42 Найти цитируемый пост)
 с таким подходом проще всего писать все на чистом Си (спасибо, что не на ассемблере).

Если бы в чистых Сях была бы поддержка ООП, да шаблоны, то я бы писал именно на них. Но тогда это были бы не Cи  smile 

Цитата(Void @  5.7.2006,  23:42 Найти цитируемый пост)
Но ведь исключение выбрасывается в исключительных ситуациях, если это не так, то напрашивается вывод об ошибках дизайна. А значит потери производительности минимальны. 

Ладно... согласен. Но все же для портируемости лучше юзать перечесление...
К тому же, что чисто психологически делать проще ?
Код

switch(class_obj.Metod())
{
case fyb_do_err: log_err << " 'do it really' -exception";break;
case more: break;
//default: log_err << "unreferenced error"; /*кстати вот здесь есть преимущество у исключений, unreferenced error в данном случае отловить невозможно*/
}

или:
Код

try{class_obj.Metod();}
catch(fyb){log_err << " 'do it really' -exception";}//f.y.b - fuck you brain
catch(more){//...;}
catch(...){log_err << "unreferenced exception";}

Меня пугает множество фигурных скобок.
ЗЫ Скобки, скобки, скобки... вложенности, много вложенностей, они, они,идут за мной(после Макконелла я не люблю вложенности, скобки и всё что с ними связанно).

Добавлено @ 20:46 
Void
А вот умеет у тебя механизм отлова исключений действовать так ? smile
Код

ErrType tmperr = class_obj.Metod();
if(tmperr>ERR_RANGE1 && tmperr < ERR_RANGE20) do_some();
 

Это сообщение отредактировал(а) En_t_end - 5.7.2006, 20:49
PM MAIL ICQ Skype GTalk Jabber   Вверх
Xenon
Дата 5.7.2006, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



En_t_end, Но зато, если нормально продумать ... Надо будет тебе, допустим, изменить сообщение об ошибки - меняешь только в catch блоке и все. И централизация. 


--------------------
user posted image  
PM MAIL   Вверх
En_t_end
Дата 5.7.2006, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



XenonSk
что-то я не пойму, где децентрализация, при использовании перечеслений ?

Добавлено @ 20:56 
XenonSk
Надо мне будет изменить сообщение об ошибке я прежде всего изменю его в константных полях, а если надо заюзать новое сообщение, то изменю одну или две строчки в case блоке. 
PM MAIL ICQ Skype GTalk Jabber   Вверх
Xenon
Дата 5.7.2006, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



En_t_end, ну просто, допустим, у тебя 8 методов, в которых может произойти одна и таже ошибка. По-мойму проще будет изменить в catch Одну сторку, чем там в каждом методе менять.
А централизациия - в смысле обработка ошибок в одном месте ... 


--------------------
user posted image  
PM MAIL   Вверх
DeadSoul
Дата 5.7.2006, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(En_t_end @  5.7.2006,  20:34 Найти цитируемый пост)
Ладно... согласен. Но все же для портируемости лучше юзать перечесление...

С каких пор исключения стали непереносимыми?

Не надо учить других своей ненависти к исключениям 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Fazil6
Дата 5.7.2006, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата

Если хочешь мнение, то я бы не стал возвращать в твоем случае false, 0, NULL, минимум - вернул бы enum ErrType{...}; Исключение вообще не стал бы кидать. Просто заведи в классе тот же enum ErrType{NO_ERROR=0,OUT_OF_RANGE=-100}; В каждом методе возьми за привычку(если это не void) возвращать ErrType и получишь практически "бесплатный" расширяемый класс(можешь кроме OUT_OF_RANGE и ещё что-нибудь добавить).

и тем самым заставить каждый раз при вызове метода класса проверять, что вернули????!!!!! Очень интересно. А если я забуду проверить? А если после меня кто-то будет этот код сопровождать?

Хорошо, проверил я и вижу, что мне вернули ошибку. Дальше что? Самому по этапу передавать наверх? А там проверят и дальше ошибку возвратят? Так вся программа превратится в сплошной if-else.
Исключение нужно для обработки ошибки не там, где она возникла, а там, где ее можно и нужно обработать.  
En_t_end,
Цитата

А вот умеет у тебя механизм отлова исключений действовать так ?

ты это серьезно?
 
Код

try
 {
   class_obj.Metod();
 }
catch(const RangeError &err)
{
   if((err.tmperr>ERR_RANGE1) && (err.tmperr < ERR_RANGE20)) DoSome();
   else
       DoElse()
}


причем самый главный витамин в том, что throw RangeError(); совсем не обязательно кидался в class_obj.Metod(), а где-нибудь в глубинах кода, вызываемого в ней и не надо без конца проверять где и что вернулось.

XenonSk
Цитата

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

это неправильно. Никогда не надо так делать даже если это работает. Всегда нужно создавать объект исключения.  
PM MAIL   Вверх
Dray
Дата 5.7.2006, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Материалист
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 7.10.2003
Где: г. Всеволожск

Репутация: 2
Всего: 6



Цитата(Fazil6 @  5.7.2006,  21:56 Найти цитируемый пост)
Всегда нужно создавать объект исключения.

Так все таки лучше свой? 


--------------------
忍者

user posted image
PM MAIL   Вверх
Fazil6
Дата 5.7.2006, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата

Так все таки лучше свой? 

эта моя фраза относится в первую очередь к throw "Error", а свое или нет
это от ситуации зависит. если не надо информацию передавать, а только сигнализировать, то сойдет и пустой класс
Цитата

class MyError{};


throw MyError();

catch(const MyError &err)
{}


сдругой стороны учитывай как и где исключения будут обрабатываться. Если обработка для разных эксепшенов одинаковая, то может быть нет смысла для каждой ошибки генерить отдельное исключение, а использовать какое-то одно. 
Если ты хочешь в объекте исключения передавать какие-то данные и несколько, то здесь без своего класса трудно обойтись.
А бывают ситуации когда идет какая-то обработка данных и при ошибках надо просто прервать работу сообщив что где не так , тут и std::runtime_error вполне сгодится и писать что-то свое совсем не обязательно   
PM MAIL   Вверх
En_t_end
Дата 6.7.2006, 07:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Fazil6
Цитата(Fazil6 @  6.7.2006,  01:56 Найти цитируемый пост)
ты это серьезно?

Ептс... конечно... видимо воображение у меня слабова-то smile
Цитата(Fazil6 @  6.7.2006,  01:56 Найти цитируемый пост)
! Очень интересно. А если я забуду проверить? А если после меня кто-то будет этот код сопровождать?

Я не уверен, но в бизнес-проектах, насколько мне известно, документируют каждый метод от сих до сих. К тому же не увидеть, что  метод возвращает ErrType или тому подобную вещь, с приставкой Err - просто невозможно, бросается в глаза.
И к тому же я не говорю о том, чтобы использовать перечесление, как способ сигнализации об ошибке только в одном методе. Когда ты примешь эту концепцию во всём классе, библиотеке классов, то никаких проблем с вижу-не вижу,отлавливаю-не отлавливаю ИМХО быть не должно.
Далее... почему ты думаешь, что с исключениями дела обстоят лучше ? Человек также может не заметить, что метод может бросать некое исключение и не сделать вокруг него try{}catch()catch(...) - ТАК что тут у исключений и перечеслений одинаковые шансы на нерадивого программиста.
Цитата(DeadSoul @  6.7.2006,  01:39 Найти цитируемый пост)
С каких пор исключения стали непереносимыми?

Они наоборот СТАЛИ переносимыми только с некоторых пор. 
PM MAIL ICQ Skype GTalk Jabber   Вверх
takedo
Дата 6.7.2006, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: 1
Всего: 3



в данный момент я согласен с  En_t_end, потому что считаю удобным сделать вообще в енуме NotError = 0, и когда функция выполняется делать так: 
Код

if(Func())
{
//а здесь обрабатываем ошибку
}

Если же у нас исключение, то надо эту функцию обрамлять в трай сатч, что не всегда удобно.

Добавлено @ 08:31 
да, кстати, чуть не забыл: smile нам ведь вообще не всегда надо обрабатывать ошибку! А если это так, то генерация исключения дороже просто ничего не делания smile  


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
Fazil6
Дата 6.7.2006, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



En_t_end
Цитата

Далее... почему ты думаешь, что с исключениями дела обстоят лучше ? Человек также может не заметить, что метод может бросать некое исключение и не сделать вокруг него try{}catch()catch(...) - ТАК что тут у исключений и перечеслений одинаковые шансы на нерадивого программиста.

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

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

На самом деле эксепшены - лучшие друзья программиста.
 
PM MAIL   Вверх
ptr
Дата 6.7.2006, 10:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 1
Всего: 14



Цитата(takedo @  6.7.2006,  12:28 Найти цитируемый пост)
Если же у нас исключение, то надо эту функцию обрамлять в трай сатч, что не всегда удобно.

Не вижу ничего неудобного. В случае try/catch мы сразу видим, что внутри порождается исключение, а в твоём случае непонятно что возвращается. Да и кроме того, что если функции надо возвращать какие-то значения?

Цитата(takedo @  6.7.2006,  12:28 Найти цитируемый пост)
да, кстати, чуть не забыл: smile нам ведь вообще не всегда надо обрабатывать ошибку! А если это так, то генерация исключения дороже просто ничего не делания smile   

Не намного то и дороже.

Цитата(Fazil6 @  6.7.2006,  13:54 Найти цитируемый пост)
На самом деле эксепшены - лучшие друзья программиста.

Полностью согласен. 


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Fazil6
Дата 6.7.2006, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата(takedo @ 6.7.2006,  09:28)
в данный момент я согласен с  En_t_end, потому что считаю удобным сделать вообще в енуме NotError = 0, и когда функция выполняется делать так: 
Код

if(Func())
{
//а здесь обрабатываем ошибку
}

Если же у нас исключение, то надо эту функцию обрамлять в трай сатч, что не всегда удобно.


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

А если твоя Func() вызывает функции, которые вызывают другие функции, которые вызывают еще функции, а те вызывают еще функции и т.д. и каждая может неотработать и вернуть ошибку? Каждый вызов проверять что вернули? Это дешевле? То, что Func возвращает 0 ничего не говорит о том, что произошло и где и как на это реагировать. Для того чтобы это обеспечить нужно возвращать разные коды, а это превратит твой if в мало понятный и уродливый if - else - if - .... или switch . Я как представлю, брр...

На самом деле эксепшены - лучшие друзья программиста. 
PM MAIL   Вверх
Dray
Дата 6.7.2006, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Материалист
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 7.10.2003
Где: г. Всеволожск

Репутация: 2
Всего: 6



Эксепшены - вещь хорошая тут спорить несчем. Насчет выбора исключения я все понял, спасибо всем. 


--------------------
忍者

user posted image
PM MAIL   Вверх
En_t_end
Дата 6.7.2006, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Fazil6
Я думаю это вопрос религии. И да, действительно, я не знаю о чем говорю, потому что ни разу не встречался с более менее сложной структурно задачей. Но в мелких проектах у меня есть и перечисления и исключения, поэтому всё же я могу сравнить. Я предпочитаю перечисления("В г%вне, да не в обиде"(с))
 
PM MAIL ICQ Skype GTalk Jabber   Вверх
takedo
Дата 6.7.2006, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 501
Регистрация: 1.6.2005

Репутация: 1
Всего: 3



Fazil6, логично говоришь... и я с тобой во многом согласен, но почему в виндовс повсюду используется GetLastError()?. А возвращает она несколько тысяч разных вариантов, наверное "неудобно" обрабатывать несколько тысяч исключений? А так ::AfxMessageBox("%d",номер ошибки);- можешь ассоциировать строку с номером. И считай все рассказал, почему и зачем ошибка.
Все надо делать в меру. smile

Добавлено @ 18:03 
Fazil6
Цитата
детский сад
 ну не все здесь асы как некоторые, многие вообще здесь учатся, а потом с благодарностью также с другими начинающими делятся знанием. Да и вообще, каждый имеет право на свое мнение. Вопрос был задан, значит ответа у человека не было, после поста он обогатился усточиой позицией. Если нет противоречий - откуда ему свою позицию получить?
Как сказал 
En_t_end, и фраза хороша:
Цитата
("В г%вне, да не в обиде"(с))
 smile  


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
_hunter
Дата 6.7.2006, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



Цитата(takedo @  6.7.2006,  17:59 Найти цитируемый пост)
логично говоришь... и я с тобой во многом согласен, но почему в виндовс повсюду используется GetLastError()?

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

Цитата(takedo @  6.7.2006,  17:59 Найти цитируемый пост)
А возвращает она несколько тысяч разных вариантов, наверное "неудобно" обрабатывать несколько тысяч исключений?

так и ты в коде вряд ли все возвращаемые значения обрабатываеш -- хорошо если десяток... 


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Void
Дата 6.7.2006, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Цитата(takedo @  6.7.2006,  19:59 Найти цитируемый пост)
но почему в виндовс повсюду используется GetLastError()

Потому что WinAPI никакого отношения к C++ не имеет и бросать C++-исключения тоже не умеет. 


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
En_t_end
Дата 6.7.2006, 19:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



ОФФТОП...
Цитата(Void @  6.7.2006,  22:59 Найти цитируемый пост)
бросать C++-исключения тоже не умеет. 

Я думаю, если бы даже винда умела это делать, это превратилось бы в очередной бардак. 

Еще по исключениям...они кстати имеют goto-начало(Уолтер Савитч "Программирование С++")... я ещё пристально не смотрел дизассемблером, но мне кажется, если сравнить goto и try-catch в ассемблерном листинге, то можно найти много общего. И вообще, кого я читал, все пишут, что с исключениями надо обращаться внимательно и кидать их направо и налево не стоит. Вообще, как тут уже говорили - исключения, исключительно для исключительных операций, и хоть не обязательно, но программа после выброса должна завершиться.... ибо я себе просто не представляю, как после нескольких десятков(наверное в крупном проекте их будет и больше) goto-подобных переходов,программа может нормально функционировать. 
PM MAIL ICQ Skype GTalk Jabber   Вверх
Daevaorn
Дата 6.7.2006, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(En_t_end @  6.7.2006,  20:38 Найти цитируемый пост)
Вообще, как тут уже говорили - исключения, исключительно для исключительных операций, и хоть не обязательно, но программа после выброса должна завершиться.... ибо я себе просто не представляю, как после нескольких десятков(наверное в крупном проекте их будет и больше) goto-подобных переходов,программа может нормально функционировать

Как раз в этом то и преимущество исключений, что после их обработки можно продолжить выполение программы. Раскрутка стека со стороны компилятора, правильное упраление памятью и "правильные" деструторы со стороны разработчика - помогут не упасть программе. Попытаться востановиться после сбоя - это задача для грамотно спроектированного приложения. Не всегда получается, но всё же. 
PM MAIL WWW   Вверх
Void
Дата 6.7.2006, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



En_t_end, скажем так, и goto и исключения являются разновидностями continuations.
Цитата(En_t_end @  6.7.2006,  21:38 Найти цитируемый пост)
я ещё пристально не смотрел дизассемблером, но мне кажется, если сравнить goto и try-catch в ассемблерном листинге, то можно найти много общего.

А у if и goto в ассемблерном листинге меньше общего? Тем более механизмы реализаций исключений зависят от компилятора. MSVC так вообще пользуется сервисами ОС для этого. 


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Fazil6
Дата 7.7.2006, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



если хотите, идемте в холивары. Модеры вполне могут перенести тему.
Цитата

Еще по исключениям...они кстати имеют goto-начало(Уолтер Савитч "Программирование С++")... я ещё пристально не смотрел дизассемблером, но мне кажется, если сравнить goto и try-catch в ассемблерном листинге, то можно найти много общего.

Ничего общего. Даже по смыслу, не то что по реализации. Первый раз встречаю мысль когда goto сравнивают с исключениями. Исключения - механизм обсолютно предсказуемый и понятно работающий в отличии от goto. 
Цитата

виндовс повсюду используется GetLastError()

я скажу еще категоричнее  это совершенно другой язык программирования
Цитата

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

что в этом плохого что она завершится? Что хорошего, когда программа продолжит работать если правильно она работать не может?
а вот и ответ
Цитата

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

Попробуйте подходить к разработке программы не с позиции обеспечения в первую очередь устойчивой работы, а с позиции когда программа чуть что - бросает исключение и ложится набок с криком "ошибка такая-то в такой-то строке, потому, что индекс масива меньше нуля". Как не дико это выглядит для некоторых, но после буквально первой компиляции и запуска вашей программы Вы отловите столько багов за 30 минут тестирония!!!! причем иногда в таких местах, где вам и в голову не могло прити проверить или где дебагером проблематично проверить. Это иногда называют  самотестируемое ПО. 
А теперь представьте приходит письмо от заказчика "классная программа все зае..сь, но какая-то хрень. На прошлой неделе по программе Петров отработал 2 часа, а он клянется на полный рот казявок, что 8 отработал. В прошлом месяце такаяже хрень была с Сидоровым и Ивановым. Мы их конечно послали подальше, но вчера она так насчитала генеральному тов. Л.Трубецкому. Разберитесь в чем дело. Мы же за программу Вам 100 баксов заплатили." Вот Вам прелести сопровождения...

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

Ах да! Каюсь. Грешен. Как же я мог забыть!!!!!! Ведь для отлова исключения надо писать try, а это не всегда удобно...
Про эфективность еще вспомнили... Эксепшены - это дорого. Не дороже проверок, зато надежнее 

На самом деле эксепшены - лучшие друзья программиста.  
PM MAIL   Вверх
En_t_end
Дата 7.7.2006, 06:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Цитата(Fazil6 @  7.7.2006,  04:44 Найти цитируемый пост)
Что хорошего, когда программа продолжит работать если правильно она работать не может?

Я был бы очень рад, если бы смог научиться проектировать именно такие приложения. Если в программе, написанной для робота-исследователя Марса(к примеру) будет допущена ошибка, то, если в её случае канал связи оборвется(робот выключиться), то будут потерянны миллионы. Программа робота должна сама восстановиться, или минимум отключить модуль, в котором обнаруженна ошибка.
С исключениями это будет проблематично. После catch-отлова нескольких взаимосвязанных багов, нужно будет применить довольно много методов для возвращения к нужной позиции.  Кстати скорее всего придется использовать go to.
Цитата(Fazil6 @  7.7.2006,  04:44 Найти цитируемый пост)
то иногда называют  самотестируемое ПО. 

Согласен, но выпускать такое ПО к заказчику нельзя.

Кстати, какая польза от раскрутки стека, если, к примеру, я память в большинстве случаев из кучи использую ?

Добавлено @ 06:58 
Цитата(Fazil6 @  7.7.2006,  04:44 Найти цитируемый пост)
 Первый раз встречаю мысль когда goto сравнивают с исключениями.

Не знаю, может эта мысль родилась только в голове у Савитча, но мне почему-то кажется, что это не так.
Цитата(Fazil6 @  7.7.2006,  04:44 Найти цитируемый пост)
Исключения - механизм обсолютно предсказуемый и понятно работающий в отличии от goto. 

Никто не спорит, но вот само прыгания из любого места программы вызывает опасения.
 
PM MAIL ICQ Skype GTalk Jabber   Вверх
Earnest
Дата 7.7.2006, 07:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Любая программа может и должна работать устойчиво к исключениям. И нет тут ничего эзотерического. Скажем, нужно открыть файл. Идем в меню, Open, выбираем файл, а файл... не тот. Скажем, какой-то умник переименовал tif в bmp ... Или просто в двоичном редакторе пошалил... или система упала в момент записи... И что, аварийно завершаться? Даже не смешно. Приличная программа должна сказать "вас здесь не стояло" и нормально продолжаться. 
И это относится к чему угодно: запустили проверку, ну не знаю, правописания, в набитом тексте. Что-то там не сошлось (34 буква алфавита обнаружилась, или язык внезапно стал албанским, или просто памяти не хватило, или...). Очевидно, что завершиться должна только эта конкретная функция, да так, чтобы остальная часть программы не пострадала, и можно было продолжать работу. С помощью исключений это реализовать несложно - нужно только придерживаться определенной дисциплины. А насчет использования кучи - так на то есть техника "Выделение ресурса есть инициализация", уже давно с бородой. 


--------------------
...
PM   Вверх
likehood
Дата 7.7.2006, 09:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



Цитата(Earnest @  7.7.2006,  08:07 Найти цитируемый пост)
 или язык внезапно стал албанским

 smile  smile  smile  
PM MAIL   Вверх
Fazil6
Дата 7.7.2006, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



En_t_end
Цитата

Я был бы очень рад, если бы смог научиться проектировать именно такие приложения. Если в программе, написанной для робота-исследователя Марса(к примеру) будет допущена ошибка, то, если в её случае канал связи оборвется(робот выключиться), то будут потерянны миллионы. Программа робота должна сама восстановиться, или минимум отключить модуль, в котором обнаруженна ошибка.

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

En_t_end
Цитата

С исключениями это будет проблематично. 

как раз с исключениями проще всего
Цитата

После catch-отлова нескольких взаимосвязанных багов, нужно будет применить довольно много методов для возвращения к нужной позиции.  Кстати скорее всего придется использовать go to.

ржунимагу. Какое goto, какая позиция? Идея обработки исключения заключается в том, что с помощью исключения мы автоматически попадаем туда, где мы можем правильно восстановиться после ошибки. Куда еще нужно переходить?
Цитата

Согласен, но выпускать такое ПО к заказчику нельзя.

Какое нельзя? Тщательно протестированное? 
Цитата

Кстати, какая польза от раскрутки стека, если, к примеру, я память в большинстве случаев из кучи использую ?

boost::shared_ptr
tr1::shared_ptr
std::auto_ptr

Earnest
Цитата

Любая программа может и должна работать устойчиво к исключениям. И нет тут ничего эзотерического. Скажем, нужно открыть файл. Идем в меню, Open, выбираем файл, а файл... не тот. Скажем, какой-то умник переименовал tif в bmp ... Или просто в двоичном редакторе пошалил... или система упала в момент записи... И что, аварийно завершаться? Даже не смешно. Приличная программа должна сказать "вас здесь не стояло" и нормально продолжаться.

Я же не говорю, что исключения надо бросать и не обрабатывать.  Можешь восстановиться - продолжай себе работать. Я нигде не сказал, что по любому эксепшену надо аварийно завершаться. 
 
PM MAIL   Вверх
_hunter
Дата 7.7.2006, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



попробую объясеить кодом.
все, наверное, знают такую "замечательную" библиотеку как WinInet
и работа с ней просто "замечательная":

Код

void UploadFile(...)
{
    connection = InternetConnect();
    if (!connection)
    {
        DWORD error = ::GetLastError();
        CString lastError = WinInetError(error);//потому как пользователю текст ошибки показать нужно
        return error;//потому как для обработки ошибки нужен ее код
    }

    request = HttpOpenRequest(_connection, "POST", _serverPath, NULL, NULL, NULL, 
    if (!request)
    {
        DWORD error = ::GetLastError();
        CString lastError = WinInetError(error);//потому как пользователю текст ошибки показать нужно
        return error;//потому как для обработки ошибки нужен ее код
    }

    if (!HttpSendRequestEx())
    {
        DWORD error = ::GetLastError();
        CString lastError = WinInetError(error);//потому как пользователю текст ошибки показать нужно
        return error;//потому как для обработки ошибки нужен ее код
    }

    if (!InternetWriteFile())
    {
        DWORD error = ::GetLastError();
        CString lastError = WinInetError(error);//потому как пользователю текст ошибки показать нужно
        return error;//потому как для обработки ошибки нужен ее код
    }

    if (!HttpEndRequest())
    {
        DWORD error = ::GetLastError();
        CString lastError = WinInetError(error);//потому как пользователю текст ошибки показать нужно
        return error;//потому как для обработки ошибки нужен ее код
    }
}

и в месте вызова смотрим на возвернутый код ошибки и думаем что нам с ним делать


а были бы в ней исключения -- все было бы просто замечательно:
Код

void UploadFile(...)
{
    connection = InternetConnect();

    request = HttpOpenRequest(_connection, "POST", _serverPath, NULL, NULL, NULL, 

    HttpSendRequestEx();

    InternetWriteFile();

    HttpEndRequest();
все.   
а в месте вызова ловим исключение.
}

 


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Dray
Дата 7.7.2006, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Материалист
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 7.10.2003
Где: г. Всеволожск

Репутация: 2
Всего: 6



Великолепный пример! Много раз с таким встречался и ругался на всю эту проверку ифами. В том же Direct X такая ерунда. ИМХО эксепшены конечно удобней!
За такой пример плюс. 


--------------------
忍者

user posted image
PM MAIL   Вверх
En_t_end
Дата 8.7.2006, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Цитата(Fazil6 @  6.7.2006,  01:56 Найти цитируемый пост)
причем самый главный витамин в том, что throw RangeError(); совсем не обязательно кидался в class_obj.Metod(), а где-нибудь в глубинах кода, вызываемого в ней и не надо без конца проверять где и что вернулось.

Спасибо! Благодаря этому примеру, я смог упростить очень важный для меня код. Я смог выбросить более половины бесмысленных проверок, в результате код-реализация уменьшился в два раза. 
PM MAIL ICQ Skype GTalk Jabber   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.2057 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.