Работу какой сложности допустимо осуществлять в catch?
От: ParfenMyshkin  
Дата: 07.05.11 22:19
Оценка:
Нормально ли добавить в catch относительно сложную логику, добавить внутри try и, возможно не один. Или необходимость составления программы именно таким образом (как в приведенном по ссылке фрагменте кода) является признаком того, что от механизма исключений надо отказаться и перейти к возврату кодов ошибок из функций?

Фрагмент кода
здесь
Re: Работу какой сложности допустимо осуществлять в catch?
От: alexeiz  
Дата: 07.05.11 23:49
Оценка:
Здравствуйте, ParfenMyshkin, Вы писали:

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


PM>Фрагмент кода

PM>здесь

Ничего, сойдёт и так. Только фон сделай посветлее и шрифты поменяй.
Re: Работу какой сложности допустимо осуществлять в catch?
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 08.05.11 00:12
Оценка:
Здравствуйте, ParfenMyshkin, Вы писали:

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


PM>Фрагмент кода

PM>здесь

Так писать однозначно не стоит.

Выложи текст программы, а не картинку. Твой код можно ужать где то до 5-10 строчек без потери читабельности.
Re: Работу какой сложности допустимо осуществлять в catch?
От: Ytz https://github.com/mtrempoltsev
Дата: 08.05.11 05:19
Оценка:
Здравствуйте, ParfenMyshkin, Вы писали:

PM>Нормально ли


Совершенно ненормально!
1. Это спагетти-код где вместо goto используется try-catch
2. Не стоит реализовывать логику на исключениях
Re[2]: Работу какой сложности допустимо осуществлять в catch
От: ParfenMyshkin  
Дата: 08.05.11 08:44
Оценка:
Ytz>Совершенно ненормально!
Ytz>1. Это спагетти-код где вместо goto используется try-catch
Ytz>2. Не стоит реализовывать логику на исключениях


Спасибо. А может есть источник где об этом случае с логикой в исключениях подробно написано? Подскажите, пожалуйста. Получается, что использование механизма исключений ограничено случаями с простой логикой обработки ошибки?
Re[3]: Работу какой сложности допустимо осуществлять в catch
От: Ytz https://github.com/mtrempoltsev
Дата: 08.05.11 09:07
Оценка: 3 (1)
Здравствуйте, ParfenMyshkin, Вы писали:

Ytz>>Совершенно ненормально!

Ytz>>1. Это спагетти-код где вместо goto используется try-catch
Ytz>>2. Не стоит реализовывать логику на исключениях

PM>Спасибо. А может есть источник где об этом случае с логикой в исключениях подробно написано? Подскажите, пожалуйста. Получается, что использование механизма исключений ограничено случаями с простой логикой обработки ошибки?


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

Почитать можно, например, Герба Саттера. У него в "Новые сложные задачи на C++" есть раздел по вопросам использования исключений.
Re[4]: Работу какой сложности допустимо осуществлять в catch
От: ParfenMyshkin  
Дата: 08.05.11 10:08
Оценка:
Здравствуйте, Ytz, Вы писали:

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


Ytz>>>Совершенно ненормально!

Ytz>>>1. Это спагетти-код где вместо goto используется try-catch
Ytz>>>2. Не стоит реализовывать логику на исключениях

PM>>Спасибо. А может есть источник где об этом случае с логикой в исключениях подробно написано? Подскажите, пожалуйста. Получается, что использование механизма исключений ограничено случаями с простой логикой обработки ошибки?


Ytz>Исключение — это ошибка после которой невозможно корректная работа кода, например нет памяти. Очевидно, что например нажатие не той кнопки пользователем, к таким ситуациям не относится — это просто один из случаев обработки действий пользователя. Использование исключений в таком случае просто усложнит код и ухудшит быстродействие.


Ytz>Почитать можно, например, Герба Саттера. У него в "Новые сложные задачи на C++" есть раздел по вопросам использования исключений.


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

errorCode = runRequest(param);
if(errorCode == PasswordNeeded)
{
errorCode = runRequest(Password);
if(errorCode == someErrorCode)
doSomething();
else
.....
}
Re[2]: Работу какой сложности допустимо осуществлять в catch
От: ParfenMyshkin  
Дата: 08.05.11 10:27
Оценка:
Здравствуйте, Ikemefula, Вы писали:

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


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


PM>>Фрагмент кода

PM>>здесь

I>Так писать однозначно не стоит.


I>Выложи текст программы, а не картинку. Твой код можно ужать где то до 5-10 строчек без потери читабельности.



Не стоит так писать — в смысле не стоит использовать механизм исключений или в смысле фоматированя строк кода. Спасибо.
Re[3]: Работу какой сложности допустимо осуществлять в catch
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 08.05.11 11:04
Оценка:
Здравствуйте, ParfenMyshkin, Вы писали:

I>>Так писать однозначно не стоит.


I>>Выложи текст программы, а не картинку. Твой код можно ужать где то до 5-10 строчек без потери читабельности.


PM>Не стоит так писать — в смысле не стоит использовать механизм исключений или в смысле фоматированя строк кода. Спасибо.


В смысле длинны фунции и количества вложеных блоков.

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

Что бы показать, как побороть это в твоем коде мне нужен твой текст.
Re[5]: Работу какой сложности допустимо осуществлять в catch
От: Valen  
Дата: 08.05.11 12:03
Оценка: 3 (1)
Здравствуйте, ParfenMyshkin, Вы писали:

PM>У меня тоже сомнения, что это действительно исключения. Вообще, требование ввода пароля — это штатная ситуация.

PM>Может отказаться от генерации исключений и сделать через возвращаемые коды ошибки так:

PM>errorCode = runRequest(param);

PM>if(errorCode == PasswordNeeded)
PM>{
PM> errorCode = runRequest(Password);
PM> if(errorCode == someErrorCode)
PM> doSomething();
PM> else
PM> .....
PM>}
Имхо этот вариант лучше. Только я бы сделал через switch

switch errorCode{
case (PasswordNeeded):
case (someErrorCode):
default throw Exception / или что-то вроде этого
}



В книге, которую Вам порекомендовали, автор ставит одним из плюсов исключения то, что мимо него "нельзя пройти мимо". Функция может вернуть значение "Ошибка", но программист может забыть проверить результат на это значение и программа будет работать, находясь в некорректном состоянии. Исключение же, если не будет поймано, остановит работу программы.
Потому default в switch обязателен, версию протокола могут поменять, он может вернуть новый код ошибки. Тогда отработает default.
Re[4]: Работу какой сложности допустимо осуществлять в catch
От: ParfenMyshkin  
Дата: 08.05.11 12:18
Оценка:
Здравствуйте, Ikemefula, Вы писали:

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


I>>>Так писать однозначно не стоит.


I>>>Выложи текст программы, а не картинку. Твой код можно ужать где то до 5-10 строчек без потери читабельности.


PM>>Не стоит так писать — в смысле не стоит использовать механизм исключений или в смысле фоматированя строк кода. Спасибо.


I>В смысле длинны фунции и количества вложеных блоков.


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


I>Что бы показать, как побороть это в твоем коде мне нужен твой текст.


http://myshkin.blog.net.ua/files/2011/05/public2.txt
Re[4]: Работу какой сложности допустимо осуществлять в catch
От: cli  
Дата: 08.05.11 13:38
Оценка:
Здравствуйте, Ytz, Вы писали:

Ytz>Исключение — это ошибка после которой невозможно корректная работа кода, например нет памяти.

Ytz>Почитать можно, например, Герба Саттера. У него в "Новые сложные задачи на C++" есть раздел по вопросам использования исключений.

Для начала стоит почитать Страуструпа — 14.5 Исключения, не являющиеся ошибками.
Исключение может так же быть удобным способом вернуться из глубоко вложенного кода, например из рекурсивного поиска с вызовом деструкторов локальных объектов.
Re[5]: Работу какой сложности допустимо осуществлять в catch
От: ParfenMyshkin  
Дата: 08.05.11 15:36
Оценка:
Здравствуйте, cli, Вы писали:

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


Ytz>>Исключение — это ошибка после которой невозможно корректная работа кода, например нет памяти.

Ytz>>Почитать можно, например, Герба Саттера. У него в "Новые сложные задачи на C++" есть раздел по вопросам использования исключений.

cli>Для начала стоит почитать Страуструпа — 14.5 Исключения, не являющиеся ошибками.

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

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

Саттер и другие приводят полезные, но очень общие рекомендации. Не могу найти где-нибудь конструкцию, похожую на приведенную в листинге. Поэтому и возникли сомнения, что так хорошо делать. Хотелось бы найти авторитетный источник, который бы явно приводил похожий пример с логикой через исключения, с вложенными в catch другими try и где бы говорилось, что это плохая практика.
Re[5]: Работу какой сложности допустимо осуществлять в catch
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 09.05.11 22:02
Оценка:
Здравствуйте, ParfenMyshkin, Вы писали:

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


I>>Что бы показать, как побороть это в твоем коде мне нужен твой текст.


PM>http://myshkin.blog.net.ua/files/2011/05/public2.txt


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

Мне лично указатели нравятся бОльше, но не всегда они приемлемы и приходится плодить слишком много методов. Здесь я привел пример на макросах.
CatchExceptionOn — макрос, который обрабатывает ошибку.

BOOL CanContinue(void)
{
  return KeyboardButton == G() && !WaitF11Confirmation();
}

int main()
{
    while(1){
        try 
        {
            F();
            break;
        }
        catch(Exception4020)
        {
            if(CanContinue()) 
                continue;
            CatchExceptionOn(P(),Exception4036, "P WITH error");
            CatchExceptionOn(R(),ExceptionRA,"");
        }
    }
}


Кстати говоря, в новом стандарте С++ есть лямбды и код можно упростить вообще до безобразия. Не в курсах синтаксиса последних плюсов, покажу пример на C#

ForseCallIgnoreException<Exception4020>
(
  () => F(),
  onError: ()=>
  {
    if(CanContinue())
      RepeatCall(); // хитрый метод !
    ForseCallIgnoreException<Exception4020>(() => P(), onError: () => print("P WITH error"));  
    ForseCallIgnoreException<ExceptionRA>(() => R(), onError:() => DoNothing());  
    RepeatCall();
  }
);
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.