try and catch, паранойя в использовании....
От: myaso  
Дата: 02.06.05 12:48
Оценка: :))) :)))
Всем привет!

У меня тут в последнее время появилось устойчивое желание использовать сабжевую конструкцию там где надо и не надо. Во всём нужно соблюдать золотую середину... Я её видать потерял чувство равновесия:( Просьба востановить! Хотя может быть я прав:)

И так. Например изначально каждую функцию я хочу оформлять вот так:
bool func()
{
    res = false;

    try
    {
        ......

        res = true;
    }
    catch (...)
    {
        res = false;
    }

    return res;
}


далее из-за боязни всего что движеться и не движеться там где я выделяю память я хочу делать вот так
bool func()
{
    res = false;

    try
    {
        void* pTmp = malloc(size);
        if (pTmp != NULL)
        {
            try
            {
                ...........

                res = true;
            }
            catch (...)
            {
                res = false;
            }

            free(pTmp);

        }        
    }
    catch (...)
    {
        res = false;
    }

    return res;
}


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

bool func()
{
    res = false;

    try
    {
        void* pTmp1 = malloc(size);
        if (pTmp1 != NULL)
        {
            try
            {
                void* pTmp2 = malloc(size);
                if (pTmp2 != NULL)
                {
                    try
                    {
                        ...........

                        res = true;
                    }
                    catch (...)
                    {
                        res = false;
                    }

                    free(pTmp2);

                }

                res = true;
            }
            catch (...)
            {
                res = false;
            }

            free(pTmp1);

        }        
    }
    catch (...)
    {
        res = false;
    }

    return res;
}


а ещё понравилось делать вот так

bool func()
{
    res = false;

    try
    {
        тут что-то делается. потом проверяется условие если фолс то делаем throw
        if (condition == false)
        {
            throw -1;
        }
        иначе продолжаем работу....

        потом ситуация может повториться
        if (condition == false)
        {
            throw -1;
        }

    }
    catch (...)
    {
        res = false;
    }

    return res;
}



Что скажите? Говорить о том что например тот же malloc или любая функция которуюя хочу дёрнуть не кидает експешин меня никоим образом не успокаивает. Я из-за недоверия ей всё равно хочу взять её в try, не смотря ни на что, даже ни смотря на более медленную работу. Вот такие пироги.

PS наверное хотелось бы для начала поговорить о С++, поэтому SEH с её __finally не стоит рассматривать.
Re: try and catch, паранойя в использовании....
От: Владик Россия  
Дата: 02.06.05 13:15
Оценка: +3
Здравствуйте, myaso, Вы писали:

M>PS наверное хотелось бы для начала поговорить о С++,


Начни для начала с изучения RAII в C++.
Как все запущенно...
Re: try and catch, паранойя в использовании....
От: GlebZ Россия  
Дата: 02.06.05 14:58
Оценка:
Здравствуйте, myaso, Вы писали:

Сначало смотрим про обертки для С++ динамических указателей и поведение объектов в стеке. Потом смотрим чем обходятся исключения в плане производительности. И получается такая шняга:
1. Вся логика программы свободно может прожить без исключений.
2. Исключениями пользуются только для исключительных случаев. (например неожиданные ошибки).

С уважением, Gleb.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[2]: try and catch, паранойя в использовании....
От: myaso  
Дата: 02.06.05 15:10
Оценка:
мг... нашёл... сейчас поизучаем...
Re: try and catch, паранойя в использовании....
От: Igor Trofimov  
Дата: 02.06.05 16:28
Оценка: 1 (1) +1
M>И так. Например изначально каждую функцию я хочу оформлять вот так:
M>
M>bool func()
M>{
M>    res = false;

M>    try
M>    {
M>        ......

M>        res = true;
M>    }
M>    catch (...)
M>    {
M>        res = false;
M>    }

M>    return res;
M>}


А зачем в среде, где есть механизм структурированной обработки исключений использовать булевский признак успешного завершения для каждой функции???
Re: try and catch, паранойя в использовании....
От: Severn Россия  
Дата: 03.06.05 03:05
Оценка: +1
Здравствуйте, myaso, Вы писали:


M>PS наверное хотелось бы для начала поговорить о С++, поэтому SEH с её __finally не стоит рассматривать.


Дык это у тебя чистейшей воды С + коды возврата, а не С++ + исключения
Re: try and catch, паранойя в использовании....
От: Дарней Россия  
Дата: 03.06.05 04:10
Оценка: +1
Здравствуйте, myaso, Вы писали:

M>И так. Например изначально каждую функцию я хочу оформлять вот так:

M>
M>bool func()
M>{
M>    res = false;

M>    try
M>    {
M>        ......

M>        res = true;
M>    }
M>    catch (...)
M>    {
M>        res = false;
M>    }

M>    return res;
M>}


это не паранойя, это чистейшей воды "возвращение в пещеры" с заменой исключений на коды возврата
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re: try and catch, паранойя в использовании....
От: mihoshi Россия  
Дата: 03.06.05 06:05
Оценка: -3
Здравствуйте, myaso, Вы писали:

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

#define assert(x) {if (!x) {throw -1;}}

void func()
{
    void *pTmp1=0, *pTmp2=0;
    try
    {
       pTmp1 = malloc(size);
       assert(pTmp1 != 0);  
       pTmp2 = malloc(size);
       assert(pTmp2 != 0);  
       ...........
    } catch (...) {
       if(pTmp1 != 0) 
         free (pTmp1);
       if(pTmp2 != 0) 
         free (pTmp2);
       throw; 
    }
}


Хотя лучше, конечно, использовать специальный тип исключения, а не int.
Re: try and catch, паранойя в использовании....
От: Eugene Kilachkoff Россия  
Дата: 03.06.05 07:08
Оценка:
Здравствуйте, myaso, Вы писали:

M>У меня тут в последнее время появилось устойчивое желание использовать сабжевую конструкцию там где надо и не надо. Во всём нужно соблюдать золотую середину... Я её видать потерял чувство равновесия Просьба востановить! Хотя может быть я прав

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

M>Что скажите? Говорить о том что например тот же malloc или любая функция которуюя хочу дёрнуть не кидает експешин меня никоим образом не успокаивает. Я из-за недоверия ей всё равно хочу взять её в try, не смотря ни на что, даже ни смотря на более медленную работу. Вот такие пироги.

Во вторых, код, подобный скипнутому нужен только в одном случае — при написании "исключительной" обертки к API, которая не поддерживает исключения, или наоборот, обработка ошибок в коде, где исключений не должно быть, а нижележащий API их выкидывает.
Вообще, предпочитаемый метод обработки определяется стилем имеющегося на данный момент кода, а также здравым смыслом.
Re[2]: try and catch, паранойя в использовании....
От: myaso  
Дата: 03.06.05 07:10
Оценка:
Всё что я могу сказать в своё оправдание, так это то что приходиться учиться по ходу(ну наверное так у всех), а время оно ограниченно:( Спасибо за коменты :)
Re[2]: try and catch, паранойя в использовании....
От: GlebZ Россия  
Дата: 03.06.05 12:55
Оценка:
Здравствуйте, mihoshi, Вы писали:

Заделать шаблончик для динамического объекта — 5 минут ручной работы (если стандартный не хочешь использовать). И тогда нафиг этот catch сдался. Лишняя писанина(да к тому-же опасная).

С уважением, Gleb.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[2]: try and catch, паранойя в использовании....
От: ansi  
Дата: 03.06.05 23:51
Оценка: 6 (1)
Здравствуйте, mihoshi, Вы писали:

M>
M>// Товарисч, букву хэ надо заключать в скобки
M>#define assert(x) {if (!(x)) {throw -1;}}

M>void func()
M>{
M>    void *pTmp1=0, *pTmp2=0;
M>    try
M>    {
M>       pTmp1 = malloc(size);
M>       assert(pTmp1 != 0);  
M>       pTmp2 = malloc(size);
M>       assert(pTmp2 != 0);  
M>       ...........
M>    } catch (...) {
M>       if(pTmp1 != 0) 
M>         free (pTmp1);
M>       if(pTmp2 != 0) 
M>         free (pTmp2);
M>       throw; 
M>    }
M>}
M>


M>Хотя лучше, конечно, использовать специальный тип исключения, а не int.
new RSDN@Home(1.1.4, 303) << new Message(); std::head::ear << "Celtic Angels — Angels Sea";
Re: try and catch, паранойя в использовании....
От: IT Россия linq2db.com
Дата: 04.06.05 03:23
Оценка: :))) :))
Здравствуйте, myaso, Вы писали:

M>И так. Например изначально каждую функцию я хочу оформлять вот так:


Срочно к доктору. Сначала к хирургу по кодам возврата (пусть это всё отрежет нафиг), потом к терапевту по исключениям.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: try and catch, паранойя в использовании....
От: myaso  
Дата: 05.06.05 13:26
Оценка:
Здравствуйте, IT, Вы писали:

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


M>>И так. Например изначально каждую функцию я хочу оформлять вот так:


IT>Срочно к доктору. Сначала к хирургу по кодам возврата (пусть это всё отрежет нафиг), потом к терапевту по исключениям.


ага... всё таки исключения есть "рулез" ? :) а как же вот это мнение?

GZ>Сначало смотрим про обертки для С++ динамических указателей и поведение объектов в стеке. Потом смотрим чем обходятся исключения в плане производительности. И получается такая шняга:

GZ>1. Вся логика программы свободно может прожить без исключений.
GZ>2. Исключениями пользуются только для исключительных случаев. (например неожиданные ошибки).
Re: try and catch, паранойя в использовании....
От: RST_Angellab  
Дата: 05.06.05 13:38
Оценка:
Исключения не всегда хорошо.
1) Исключения в деструкторе к примеру.
2) Раскрутка стека не всегда корректно отрабатывает — деструкторы могут не вызываться — были случаи, не помню конкретных примеров
3) Исключения приводят к работе ведра. Соответсвенно любой throw (-1) >= 2000 тактов процессора. Если это происходит довольно часто — даже на хороших машинах тормоза ощутимы.
Re[3]: try and catch, паранойя в использовании....
От: IT Россия linq2db.com
Дата: 05.06.05 16:08
Оценка:
Здравствуйте, myaso, Вы писали:

IT>>Срочно к доктору. Сначала к хирургу по кодам возврата (пусть это всё отрежет нафиг), потом к терапевту по исключениям.


M>ага... всё таки исключения есть "рулез" ? а как же вот это мнение?


Нормальное мнение. Использование исключений для программирования логики — это неправильно. Для исключительных ситуаций — самое оно.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: try and catch, паранойя в использовании....
От: mihoshi Россия  
Дата: 06.06.05 05:11
Оценка:
Здравствуйте, GlebZ, Вы писали:

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


GZ>Заделать шаблончик для динамического объекта — 5 минут ручной работы (если стандартный не хочешь использовать). И тогда нафиг этот catch сдался. Лишняя писанина(да к тому-же опасная).


Я писал пример того, как сделать близко к тексту изначального примера. Разумеется, личныо я сырые malloc-и в работе я не использую. Но если уж товарищу приспичило...
Re[4]: try and catch, паранойя в использовании....
От: Mika Soukhov Stock#
Дата: 06.06.05 10:00
Оценка: :)
Здравствуйте, IT, Вы писали:

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


IT>>>Срочно к доктору. Сначала к хирургу по кодам возврата (пусть это всё отрежет нафиг), потом к терапевту по исключениям.


M>>ага... всё таки исключения есть "рулез" ? а как же вот это мнение?


IT>Нормальное мнение. Использование исключений для программирования логики — это неправильно. Для исключительных ситуаций — самое оно.


Это вообще в корне неверно. На основе ошибок работают такие вещи, как: MSMQ (в зависимости от исключений, доставляются данные или нет), компиляторы (продолжается компиляция или все останавливается на этапе разбора текста) или система предупреждения атаки со стороны вредоносных систем (аудиторские системы проводят мониторинг данных, и, если хоть один их элементов не отвечает, то он закрывается от внешнего доступа).
Re[4]: try and catch, паранойя в использовании....
От: GlebZ Россия  
Дата: 06.06.05 10:36
Оценка:
Здравствуйте, mihoshi, Вы писали:

M>Я писал пример того, как сделать близко к тексту изначального примера. Разумеется, личныо я сырые malloc-и в работе я не использую. Но если уж товарищу приспичило...

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

//хотя есть системный assert, возьмем твой
#define assert(x) {if (!(x)) {throw -1;}}

//заделали свой шаблончик
template <class T>
class my_ptr
{
public:
    T* m_t;
    //здесь вместо malloc используем new. Это повысит переносимость.
    my_ptr(int size){m_t=0;m_t=new T[size];assert(m_t!=0);};
    ~my_ptr(){delete m_t;m_t=0;};
    T* operator->(){return m_t;};
    T operator*(){return *m_t;};
}; 
//и теперь все стало очень просто
//поскольку невыделение памяти - ошибка фатальная
//то лечится только остановкой программы
void func()
{
    my_ptr<char> pTmp1(100);
    my_ptr<char> pTmp2(100);
}



С уважением, Gleb.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[5]: try and catch, паранойя в использовании....
От: myaso  
Дата: 06.06.05 12:12
Оценка:
Здравствуйте, GlebZ, Вы писали:

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


M>>Я писал пример того, как сделать близко к тексту изначального примера. Разумеется, личныо я сырые malloc-и в работе я не использую. Но если уж товарищу приспичило...

GZ>Товарсчь пока на полпути к нирване и помочь ему достигнуть ее — дело каждого пионэра любящего партию и народ. Если не возражаешь, перепишу твой код. А так как у меня и настроение хорошее, даже не буду пользоваться всякими стлными штучками(чтобы показать что все просто).

GZ>
GZ>//хотя есть системный assert, возьмем твой
GZ>#define assert(x) {if (!(x)) {throw -1;}}

GZ>//заделали свой шаблончик
GZ>template <class T>
GZ>class my_ptr
GZ>{
GZ>public:
GZ>    T* m_t;
GZ>    //здесь вместо malloc используем new. Это повысит переносимость.
GZ>    my_ptr(int size){m_t=0;m_t=new T[size];assert(m_t!=0);};
GZ>    ~my_ptr(){delete m_t;m_t=0;};
GZ>    T* operator->(){return m_t;};
GZ>    T operator*(){return *m_t;};
GZ>}; 
GZ>//и теперь все стало очень просто
GZ>//поскольку невыделение памяти - ошибка фатальная
GZ>//то лечится только остановкой программы
GZ>void func()
GZ>{
GZ>    my_ptr<char> pTmp1(100);
GZ>    my_ptr<char> pTmp2(100);
GZ>}
GZ>


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