Страница 2 из 2

СообщениеДобавлено: 15.10.2007 12:35:07
bw
Bonart> Так это и есть неявный try..except в каждом методе! По быстродействию полный швах - создавать-убивать по кадру исключений на метод.

bw> Это не правда, компилятор по наличию директивы может определить использует ли метод обработку исключения и нужно ли его дополнять соответствующим кодом (машинным).

Я предлагаю использовать такую обработку (для класса) как дополняющую к обработке метода и не обязательную в объявлении и компиляции в код. Может я не понятно выражаюсь?

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

bw> например для протоколирования, уточнения (к примеру расшифровки кода ошибки или даже замены типа исключений) или проведения анализа состояния объекта и, при необходимости, разрушения самого себя и создания заново

p.s. Эти случаи не надуманы, они из личного опыта создания устойчивых систем.

..bw

СообщениеДобавлено: 15.10.2007 13:05:42
Bonart
bw писал(а):Я предлагаю использовать такую обработку (для класса) как дополняющую к обработке метода и не обязательную в объявлении и компиляции в код. Может я не понятно выражаюсь?

Дело немножко в другом: если ты обрабатываешь исключения в каждом методе - то у тебя при каждом вызове метода выполняется дополнительная работа по созданию-уничтожению кадров исключений. Это куча лишнего кода и большие тормоза - конструкции try.. сами по себе весьма не дешевые! Да, ты не будешь размножать код обработчиков, но размножишь сам перехват исключений. Посмотри на ассемблерных листингах, ЧТО генерится на каждый try..except.
bw писал(а):А вот в тех случаях когда это не так, можно использовать обработчик для объекта.

Это легко решается введением метода HandleError и вызовом его вот так:
Код: Выделить всё
begin
  ... 
finally
  ...
except
  HandleError
end;

СообщениеДобавлено: 15.10.2007 13:16:07
bw
> Да, ты не будешь размножать код обработчиков, но размножишь сам перехват исключений.
Это так. Проблема решается использованием мозга. Возможно для больших классов использование такой обработки будет неудачным решением, это в том случае когда большинство методов не должно быть подвергнуто такой обработке. Так же это неудачное решение, если методы "небольшие" и от них ожидается быстрая работа.

> Это легко решается введением метода HandleError и вызовом его вот так
Все же в тех случаях когда требуется поголовная обработка методов, вероятно, на высокоуровневых классах, это будет удобно.

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

..bw

СообщениеДобавлено: 15.10.2007 13:33:25
Bonart
bw писал(а):К тому же мы создаем идеальный язык, а не компилятор. Так что проблемы "кривой сборки" кода я бы не рассматривал.

Дороговизна перехвата исключений связана не с плохой компиляцией, а с нынешней архитектурой ЭВМ :(

СообщениеДобавлено: 15.10.2007 14:19:01
ev
а почему бы не сделать один обработчик в виде массива исключений?
если произошло исключение, то в массив добавляется информация о нем
прогрммист в любой удобный момент может посмотреть массив, очистить и т.п.

СообщениеДобавлено: 15.10.2007 14:43:57
bw
А где должен находиться этот массив, на самом верхнем уровне? Часто удобнее локализовать возникновение исключения (удобнее обработать ошибку в известном контексте), я предлагал это сделать в масштабах метода (функции) и/или класса, т.е. исключить злоупотребление и расставление в коде множества (к тому же вложенных) определений try-except.

> прогрммист в любой удобный момент
Т.е. в любой? Осмелюсь предположить что такой момент возникает в момент возникновения исключения :-) ?

..bw

СообщениеДобавлено: 15.10.2007 16:07:39
ev
А где должен находиться этот массив, на самом верхнем уровне?

да

асто удобнее локализовать возникновение исключения (удобнее обработать ошибку в известном контексте)

так оно и есть
если ты знаешь контекст - просто смотри появились ли новые коды ошибок или нет

СообщениеДобавлено: 15.10.2007 16:35:17
bw
Т.е. определять предмет (контекст) по составу ошибки?
Но ведь код будет составляться разными разработчиками и в разное время. Как же можно запихать разношерстные обработчики в один код. Я ведь правильно понял, что вход обработки исключений будет один? Что, нужно будет как-то подписывать на получение извещений об ошибках? Наподобии сигналов в линухе?

..bw

СообщениеДобавлено: 15.10.2007 20:05:08
ev
Т.е. определять предмет (контекст) по составу ошибки?

да, если где-то происходит ошибка - то ошибка заносится в это массив
что-то вроде лога ошибок получится :)

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

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

Что, нужно будет как-то подписывать на получение извещений об ошибках?

два варианта
1. программист когда ему удобно смотрит в этот массив
2. получение извещение о новой ошибке

СообщениеДобавлено: 16.10.2007 09:17:01
Bonart
ev писал(а):2. получение извещение о новой ошибке

Это масло масленое получится. Извещения об ошибках уже реализованы... в виде исключений.

СообщениеДобавлено: 16.10.2007 11:06:03
shade
А можно и вообще без исключений обойтись.

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

У меня была простая идея реализации (для x86) обработки исключений - внутри блока - компилятор знает где происходит исключение (оператор raise). Так же исключения могут передаться из вызываемых функций. Тут делаем так: если функция отрабатывает без исключения, то при возврате сбрасывает флаг cf в ноль и возвращает результат как обычно, если функция не обрабатывает исключение, то она устанавливает флаг cf в единицу, а в регистр eax записывает код исключения (или указатель на объект исключений) и возвращает управление. В вызывающем коде после вызова ставиться условный переход на обработчик исключения jc _handler.
_handler для блока try/finally
Код: Выделить всё
_handler:
push eax ; сохраняем объект-исключение (или можно использовать переменную)
<код блока finally>
pop eax ; восстанавливаем объект-исключение
stc ; устанавливаем флаг cf в 1
ret

_handler для блока try/except
Код: Выделить всё
_handler:
<код блока except>
jmp _continue ; возвращаемся к коду после блока try/except

Если в функции нет блока try/finally/except, то вставляется простой код
Код: Выделить всё
_handler: ret

Т.е. уже установленный флаг cf и регистр eax передаются далее вверх по цепочке вызова.

Оператор raise Exception.Create:
Код: Выделить всё
call Excpetion.Create ; в eax указатель на объект-исключение
stc ; устанавливаем флаг cf
jmp _handler ; переходим к обработчику


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

А для согласования кода на разных языках, нужно добавить как минимум директиву no_exception, типа как в C++ у функции можно дописать throw(), что означает, что данный код не передает никаких исключений. И если вы попытаетесь передать исключение, то компилятор поругает вас ошибкой компиляции... И требовать чтобы все экспортируемые функции использовали этот флаг или определяли его автоматически...

СообщениеДобавлено: 16.10.2007 11:18:57
Bonart
shade писал(а):А можно и вообще без исключений обойтись.

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

СообщениеДобавлено: 16.10.2007 12:31:27
Sergei I. Gorelkin
Аппаратное исключение говорит о кривизне рук программиста, только этот программист отнюдь не всегда является автором той программы, при выполнении которой произошло исключение... "Ариан-5" тому яркий пример.
Ракетостроение, конечно, совершенно особенная песня, но всяких там АСУ ТП хватает и на земле.
Отсутствие обработки аппаратных исключений будет означать непригодность языка для подобного рода задач.

СообщениеДобавлено: 16.10.2007 12:55:04
Bonart
Sergei I. Gorelkin
+1
Разумеется, аппаратные (системные) исключения надо ловить и преобразовывать в родные для языка.