Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Exit из процедуры-функции


Автор: mspuz 18.1.2008, 16:35
Всем привет!
Всегда не задумываясь использовал ф-ию Exit, если мне нужно было покинуть ф-цию в нужный момент. Но тут копался в исходниках одного "старожилы" и обнаружил, что программист шёл на что угодно, но ни когда не использовал Exit. Поспрашивал и услышал, что это действительно не рекомендуется, но почему - сказать не смогли. Действительно ли это так плохо и главное почему?!

Автор: ama_kid 18.1.2008, 16:48
например, необходимо следить за корректностью освобождения выделенной памяти, если такая была. Зачастую бездумный вызов exit может приводить к утечкам памяти, а обдуманный - к избыточности кода. Но по большому счету - имхо это вопрос привычки, из разряда религиозных войн...

Автор: mspuz 18.1.2008, 17:03
ama_kid,  А "естественный" выход из ф-ции (достигнув конца end) отслеживает утечку памяти? По моему нет. Так что следить надо всегда и exit тут ни при чем.

Автор: ama_kid 18.1.2008, 17:13
Цитата(mspuz @  18.1.2008,  17:03 Найти цитируемый пост)
А "естественный" выход из ф-ции (достигнув конца end) отслеживает утечку памяти? По моему нет. Так что следить надо всегда и exit тут ни при чем. 
Следить-то надо всегда, но ляпнув exit не подумав - ты получишь утечку, подумав и ляпнув exit совместно с операторами освобождения памяти - получишь избыточный (дублирующийся) код, о чем я и сказал в предыдущем посте...

Автор: Shaggy 19.1.2008, 15:06
Цитата(ama_kid @  18.1.2008,  19:13 Найти цитируемый пост)
подумав и ляпнув exit совместно с операторами освобождения памяти - получишь избыточный (дублирующийся) код, о чем я и сказал в предыдущем посте...

Код

With TStringList.Create Do
  Try
    Add('123');
    Exit;
    Add('321');
  Finally
    Free;
  End;

ничего не дублируется и всё корректно освобождается...

Автор: Coderr 19.1.2008, 18:05
Чего-то я сомневаюсь о правильности кода и смысла его вообще.
Строка
Код

Add('321');

не выполнится никогда. А для создания TStringList надо заводить переменную и уже ей присваивать:
Код

var
  temp: TStringList;
...
temp := TStringList.Create;

Автор: THandle 19.1.2008, 18:08
Цитата(Coderr @  19.1.2008,  18:05 Найти цитируемый пост)
не выполнится никогда. А для создания TStringList надо заводить переменную и уже ей присваивать:

Необязательно. Можно и как Shaggy написал. 

Автор: Alexeis 19.1.2008, 18:23
Цитата(ama_kid @  18.1.2008,  16:13 Найти цитируемый пост)
Следить-то надо всегда, но ляпнув exit не подумав - ты получишь утечку, подумав и ляпнув exit совместно с операторами освобождения памяти - получишь избыточный (дублирующийся) код, о чем я и сказал в предыдущем посте...


  Более красиво решать при помощи защищенных секций. Для досрочного завершения, генерим исключение и все ресурсы корректно освобождаются  smile .

Автор: MetalFan 19.1.2008, 19:27
Цитата(Alexeis @  19.1.2008,  18:23 Найти цитируемый пост)
решать при помощи защищенных секций

что это такое?   smile я что-то про такое не слышал...
по поводу сабжа - пользую exit (в сочетании с try..finally) в разумных ситуациях без оглядки) и считаю это нормальным подходом)

Автор: Alexeis 19.1.2008, 19:43
Цитата(MetalFan @  19.1.2008,  18:27 Найти цитируемый пост)
(в сочетании с try..finally) 

  Это как раз про них.

Добавлено через 3 минуты и 26 секунд
Их еще защищенными блоками зовут иногда.

Добавлено через 6 минут и 19 секунд
  Проблема exit в разрушении логики. При досрочном выходе нужно помнить чего где и когда создал или мог не создать или создал после того как писал фрагмент с exit. Функцию дополнил созданием объекта, а при выходе по exit забыл добавить удаление, вот и утечка.

Автор: MetalFan 19.1.2008, 20:41
Цитата(Alexeis @  19.1.2008,  19:43 Найти цитируемый пост)
 Проблема exit в разрушении логики. При досрочном выходе нужно помнить чего где и когда создал или мог не создать или создал после того как писал фрагмент с exit. Функцию дополнил созданием объекта, а при выходе по exit забыл добавить удаление, вот и утечка.

пишу обычно так:
Код

lSomeObject := TSomeObjectClass.Create;
try
  ...{работа с объектом lSomeObject}
  if SomeConition then exit;
  ...
  if SomeConition2 then exit;
  ...
  ...
  if SomeConitionN then exit;
  ...
finally
  lSomeObject.Free;
end;

очень так вполне удобно

Автор: Alexeis 19.1.2008, 20:52
  Тоже вариант.

Автор: Rennigth 20.1.2008, 13:39
хе! незнал что при exit блок finally все равно выполняется  smile. Вообще exit не очень лублю... антипатия какая-то к нему   smile 

Автор: MetalFan 20.1.2008, 15:25
все допустимо в разумных пределах...
имхо лучше уж exit, чем  goto)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)