Finally или как почувствовать себя идиотом

Вопросы программирования на Free Pascal, использования компилятора и утилит.

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

Ответить
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Finally или как почувствовать себя идиотом

Сообщение Cheb »

Всю жизнь добавлял выход из критической секции перед каждым вызовом Exit(). Даже когда всё тело функции обёрнутов try...finally <выход из критической секции> end;. :oops:
Давеча моё поделиЁ запустили под вайном, и оно повисло на заклиненной критической секции :oops:
Написал тест, и убедился что я таки дятел: и break, и exit наружу запускают блок finally штатно. Goto наружу невозможен, компилятор просто тебя пошлёт.

И вот я подумал: это в документации где-то прописано, или я просто слепоглухотупой? :oops:

Код: Выделить всё

{$mode objfpc}
{$apptype console}
program finally_eh;
var i: integer;
label b;
procedure a;
begin
  try
    WriteLn('exit...');
    Exit();
  finally
    WriteLn('finally');
  end;
end;
begin
  a;
  for i:= 1 to 1 do begin
    try
      WriteLn('break...');
      break;
    finally
      WriteLn('finally');
    end;
  end;
//allright, this one no go:
//finally.lpr(35,5) Error: Jump in or outside of an exception block
{
  try
    WriteLn('goto...');
    goto b;
  finally
    WriteLn('finally');
  end;
b:
}
 {$ifdef windows}
  WriteLn('Press Enter to close');
  ReadLn;
 {$endif}
end.


Код: Выделить всё

exit...
finally
break...
finally
Press Enter to close
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

Cheb писал(а): и break, и exit наружу запускают блок finally штатно.

Это штатное документированное поведение. Было в документации.
Аватара пользователя
runewalsh
энтузиаст
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Сообщение runewalsh »

Жаль только, что он менее бесплатен, чем мог бы. В C++ из-за перегруженности неявными finally традиционно реализуют zero-cost exceptions, но ведь в FPC они тоже для каждого скоупа с автотипом создаются, чтобы в 99,9% путей выполнения так и не отработать.
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

Cheb писал(а):Написал тест, и убедился что я таки дятел: и break, и exit наружу запускают блок finally штатно. Goto наружу невозможен, компилятор просто тебя пошлёт.

Написано в ожидаемом месте. Первый абзац:
If no exception occurs inside the statement List, then the program runs as if the Try, Finally and End keywords were not present, unless an exit command is given: an exit command first executes all statements in the finally blocks before actually exiting.


runewalsh писал(а):Жаль только, что он менее бесплатен, чем мог бы. В C++ из-за перегруженности неявными finally традиционно реализуют zero-cost exceptions, но ведь в FPC они тоже для каждого автотипа создаются, чтобы в 99,9% путей выполнения так и не отработать.

для локальных переменных этих самых автотипов. (для параметров автотипов, переданных, как const, try..finaly блок не сгенерируется)
Но если бы ты их руками освобождал, то смог бы сделать эффективнее?
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Написано в ожидаемом месте

:oops: :oops: :oops:

, но ведь в FPC они тоже для каждого скоупа с автотипом создаются, чтобы в 99,9% путей выполнения так и не отработать.

{$implicitexceptions off}
Аватара пользователя
runewalsh
энтузиаст
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Сообщение runewalsh »

скалогрыз писал(а):Но если бы ты их руками освобождал, то смог бы сделать эффективнее?

Да, в предположении, что OOM можно не обрабатывать (а какой может быть внятный ответ на OOM?).

Cheb писал(а):{$implicitexceptions off}

Гарантированные утечки при raise (это настолько большее зло, что я теперь аж так не делаю). Я не хочу отказываться от исключений, я хочу, чтобы информация о раскрутке хранилась извне и при необходимости сколь угодно медленно расшифровывалась на основании указателя на исполняемую инструкцию. А то -5~10% перформанса на ровном месте (pushexceptaddr+setjmp, на которые так и не будет raise).

Добавлено спустя 26 минут 54 секунды:
Нет, не так: может быть, OOM и есть смысл обрабатывать (данные там попытаться сохранить), но если уж тебе придётся (полу)-аварийно завершиться, то на парочку утёкших строк и интерфейсов можно закрыть глаза, это очень редкий и безобидный случай в сравнении с замедлением нормального сценария.
Ответить