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

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

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

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

Сообщение Cheb » 21.12.2016 14:20:06

Всю жизнь добавлял выход из критической секции перед каждым вызовом 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
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 526
Зарегистрирован: 06.06.2005 15:54:34

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

Сообщение alexs » 21.12.2016 16:41:36

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

Это штатное документированное поведение. Было в документации.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 3428
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

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

Сообщение runewalsh » 21.12.2016 17:22:55

Жаль только, что он менее бесплатен, чем мог бы. В C++ из-за перегруженности неявными finally традиционно реализуют zero-cost exceptions, но ведь в FPC они тоже для каждого скоупа с автотипом создаются, чтобы в 99,9% путей выполнения так и не отработать.
Аватара пользователя
runewalsh
постоялец
 
Сообщения: 312
Зарегистрирован: 27.04.2010 00:15:25

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

Сообщение скалогрыз » 21.12.2016 17:42:32

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 блок не сгенерируется)
Но если бы ты их руками освобождал, то смог бы сделать эффективнее?
скалогрыз
долгожитель
 
Сообщения: 1626
Зарегистрирован: 03.09.2008 02:36:48

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

Сообщение Cheb » 21.12.2016 17:45:45

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

:oops: :oops: :oops:

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

{$implicitexceptions off}
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 526
Зарегистрирован: 06.06.2005 15:54:34

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

Сообщение runewalsh » 21.12.2016 18:03:13

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

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

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

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

Добавлено спустя 26 минут 54 секунды:
Нет, не так: может быть, OOM и есть смысл обрабатывать (данные там попытаться сохранить), но если уж тебе придётся (полу)-аварийно завершиться, то на парочку утёкших строк и интерфейсов можно закрыть глаза, это очень редкий и безобидный случай в сравнении с замедлением нормального сценария.
Аватара пользователя
runewalsh
постоялец
 
Сообщения: 312
Зарегистрирован: 27.04.2010 00:15:25


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru