Замена try - catch
От: Doc Россия http://andrey.moveax.ru
Дата: 31.08.06 15:35
Оценка:
День добрый.

Вот такой вопрос возник: есть кусок кода, который "в лоб" можно написать так
try {
 if (FAILED(Foo1())) throw hr;
 ...
 if (FAILED(Foo2())) throw hr;
 ...
} 
catch (...) {
  ShowErrorMessage (hr);
}


вот только использование try не желательно. Чем заменить.
Есть вариант так
HRESULT hr  = S_OK;
do {
  hr = Foo1(); 
  if (FAILED(hr)) break;
  ...
} while (false);

if (FAILED(hr)) ShowErrorMessage (hr);


А может есть иные варианты?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Замена try - catch
От: kirill_kl  
Дата: 31.08.06 17:24
Оценка:
А почему использование исключений нежелательно?
Re: Замена try - catch
От: eaglus Россия  
Дата: 31.08.06 17:45
Оценка:
Doc>вот только использование try не желательно. Чем заменить.
Doc>Есть вариант так
Doc>
Doc>HRESULT hr  = S_OK;
Doc>do {
Doc>  hr = Foo1(); 
Doc>  if (FAILED(hr)) break;
Doc>  ...
Doc>} while (false);

Doc>if (FAILED(hr)) ShowErrorMessage (hr);
Doc>


Doc>А может есть иные варианты?


Если если надо прыгать на точку выхода из функции, с очисткой, то лучше всего goto.
Метка всего одна, не запутаешься:



Resource* res1 = NULL;
Resource* res2 = NULL;

hr = Foo1(); 
if (FAILED(hr)) goto CLEANUP;

res1 = ...;

hr = Bar2();
if (FAILED(hr)) goto CLEANUP;

res2 = ...;

CLEANUP:

if (res1)
  FreeResource(res1);

if (res2)
  FreeResource(res2);


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

Ещё читал, что так же (goto CLEANUP) в линуксовском ядре сделано.
Это удобно очень, код не засоряет тривиальной проверочной логикой и левыми циклами, а поскольку метка всего одна, ничего страшного в goto нет.
Правда, не уверен, вызываются ли деструкторы локальных объектов, если прыгаем из вложенного блока в конец внешнего.
А вариант с циклом не подойдёт, если уже есть внешний цикл — break не метку, как в C#, в C++ вроде нет.
Re[2]: Замена try - catch
От: Doc Россия http://andrey.moveax.ru
Дата: 01.09.06 09:08
Оценка:
Здравствуйте, kirill_kl, Вы писали:

_>А почему использование исключений нежелательно?


1) Программа небольшая. Везде уже сделана струкрутрная обработка ошибок.
Ради одной функции затевать обработку на эксепшенах — нет смысла.

2) Не люблю накладных расходы (даже если они копеечные), которых можно избежать.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Замена try - catch
От: Doc Россия http://andrey.moveax.ru
Дата: 01.09.06 09:08
Оценка:
Здравствуйте, eaglus, Вы писали:

E>А вариант с циклом не подойдёт, если уже есть внешний цикл — break не метку, как в C#, в C++ вроде нет.


В моем блоке нет внутренних циклов. Так что тут нет проблем.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Замена try - catch
От: Константин Л. Франция  
Дата: 01.09.06 09:24
Оценка:
Здравствуйте, Doc, Вы писали:

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


_>>А почему использование исключений нежелательно?


Doc>1) Программа небольшая. Везде уже сделана струкрутрная обработка ошибок.

Doc>Ради одной функции затевать обработку на эксепшенах — нет смысла.

Doc>2) Не люблю накладных расходы (даже если они копеечные), которых можно избежать.


они нанокопеечные
Re: Замена try - catch
От: Left2 Украина  
Дата: 01.09.06 09:48
Оценка: +1
В случае FAILED делай return (это можно обернуть в макрос).
Очистку ресурсов делай в деструкторах.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Замена try - catch
От: apple-antonovka  
Дата: 01.09.06 10:45
Оценка:
КЛ>они нанокопеечные
Смотря как реализован механизм исключений. Я бы не стал называть копеечным лишний вызов ядра, а везь throw в VC так и делает
Re[2]: Замена try - catch
От: Doc Россия http://andrey.moveax.ru
Дата: 01.09.06 13:59
Оценка:
Здравствуйте, Left2, Вы писали:

L>В случае FAILED делай return (это можно обернуть в макрос).

L>Очистку ресурсов делай в деструкторах.

Это заставит разбивать каждую функцию на несколько мелких. Иначе как при return выводить сообщения.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Замена try - catch
От: Doc Россия http://andrey.moveax.ru
Дата: 01.09.06 13:59
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>они нанокопеечные


Спорить не буду (в смысле нет такой цели). Но если все уже сделано структурно, то пихать эксшепшн еще и не красиво. IMHO идеология должна быть едина в программе (особенно если она среднего или малого размера и пишется небольшой командой или вообще одним человеком).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Замена try - catch
От: Left2 Украина  
Дата: 01.09.06 14:26
Оценка:
L>>В случае FAILED делай return (это можно обернуть в макрос).
L>>Очистку ресурсов делай в деструкторах.

Doc>Это заставит разбивать каждую функцию на несколько мелких. Иначе как при return выводить сообщения.


Через деструктор обьекта, создаваемый на стеке. В принципе, тоже можно завернуть в макрос.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Замена try - catch
От: Константин Л. Франция  
Дата: 01.09.06 14:50
Оценка:
Здравствуйте, Doc, Вы писали:

Doc>Здравствуйте, Константин Л., Вы писали:


КЛ>>они нанокопеечные


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


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