Конференция "Прочее" » Exit внутри Try/Finally [D6, XP]
 
  • Palladin © (14.11.08 13:45) [0]
    Procedure ddd;
    Var
    s:TStringList;
    Begin
    s:=TStringList.Create;
    Try
     Exit;
    Finally
     s.Free;
    End;
    End;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    ddd; // ставим breakpoint и по F7 шагаем
    end;


    у кого не D6, просьба посмотреть, выполнится s.Free или нет...
  • Сергей М. © (14.11.08 13:51) [1]
    Даже и смотреть не надо - обязан получить управление.
    Мож ты по запарке смотришь не там где лежит, а там где светлее ?
  • ПРавильный$Вася (14.11.08 13:53) [2]
    из справки семерки
    Note: Exit passes control away from the current procedure, not merely the current block. But Exit does not violate the flow of control dictated by a try..finally construct; if Exit is called inside the try clause, the finally clause is still executed.


    поведение соответствует описанию
  • Palladin © (14.11.08 13:55) [3]
    копнул глубже, и вот что получилось

    Function ddd(Const s:String;Var r:String):Boolean;
    Var
    ss:TStringList;
    Begin
    ss:=TStringList.Create;
    Try
     ss.add(s);
     Result:=s='1';
     If Result Then r:='2';
    Finally
     ss.Free;
    End;
    End;

    Function GetDDD(Const s:String;Const def:String):String;
    Begin
    If Not ddd(s,Result) Then Result:=def;
    End;

    procedure TForm1.Button1Click(Sender: TObject);
    Var
    c:Integer;
    begin
    c:=AllocMemSize;
    GetDDD('2222','14');
    ShowMessage(IntToStr(AllocMemSize-c));
    end;



    как объяснить этот феномен? :)
  • Anatoly Podgoretsky © (14.11.08 13:55) [4]
    > Palladin  (14.11.2008 13:45:00)  [0]

    Зачем проверять, справка гарантирует выполнение ветки finally  end
  • Palladin © (14.11.08 13:56) [5]

    > Сергей М. ©   (14.11.08 13:51) [1]
    > ПРавильный$Вася   (14.11.08 13:53) [2]

    не прав я был, когда грешил на "фичу" Exit, по F7 если идти внутри функции, то заходит в Finally, если по F8 то прыгает сразу на ее End;
  • Anatoly Podgoretsky © (14.11.08 13:58) [6]
    > Palladin  (14.11.2008 13:56:05)  [5]

    Ты поведению отладчика особо не доверяй.
  • Palladin © (14.11.08 14:02) [7]

    > Anatoly Podgoretsky ©   (14.11.08 13:58) [6]

    да фик сним, с отладчиком, куда 12 байт деваются? :)
  • Anatoly Podgoretsky © (14.11.08 14:06) [8]
    > Palladin  (14.11.2008 14:02:07)  [7]

    Только меня не обвиняй.
  • Сергей М. © (14.11.08 14:07) [9]

    > Palladin ©   (14.11.08 14:02) [7]


    Плюнь на них.
    Они никуда не теряются. Это работа оптимизатора менеджера памяти.

    потыкай дюжину-lheue. раз на это батон и понаблюдай:

    procedure TForm1.Button3Click(Sender: TObject);
    var
     p: PInteger;
    begin
     showmessage(inttostr(allocmemsize));
     getmem(p, 2000);
     freemem(p);
     showmessage(inttostr(allocmemsize));
    end;
  • Palladin © (14.11.08 14:10) [10]
    мда, действительно... спасибо, успокоил :)
  • Rouse_ © (14.11.08 14:10) [11]

    > да фик сним, с отладчиком, куда 12 байт деваются? :)

    Ша... никто таки никуда уже не девается :) У меня ноль кажет твоя функция :)
  • MsGuns © (14.11.08 14:16) [12]
    А разве выход из функции делается не в одном-единственном месте (это если посмотреть машкод)
    ?
  • Palladin © (14.11.08 14:17) [13]

    > Rouse_ ©   (14.11.08 14:10) [11]

    А у тебя и не D6! :)

    Мля, как идиот ковырялся, искал то - чего нет :) И каждый раз разное количество "пропадало", в зависимости от исходных данных. Думал свихнусь :)
  • oxffff © (14.11.08 14:19) [14]

    > Мля, как идиот ковырялся, искал то - чего нет :)


    Трудно искать черную кошку в черной комнате, особенно, если ее там нет.
    (Место встречи изменить нельзя)
  • Anatoly Podgoretsky © (14.11.08 14:21) [15]
    > MsGuns  (14.11.2008 14:16:12)  [12]

    В отдном, но какое это отношение имеет к finally end?
  • MsGuns © (14.11.08 14:25) [16]
    ВТакое, что финалли будет отработано в ЛЮБОМ случае
  • Ганя (14.11.08 15:23) [17]
    в шестерке был такой косяк, потом поправили
  • Mystic © (14.11.08 19:51) [18]

    > Мля, как идиот ковырялся, искал то - чего нет :) И каждый
    > раз разное количество "пропадало", в зависимости от исходных
    > данных. Думал свихнусь :)


    А ты так попробуй ;)

    procedure Test();
    begin
     GetDDD('2222','14');
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
     c:Integer;
    begin
     c:=AllocMemSize;
     Test();
     ShowMessage(IntToStr(AllocMemSize-c));
    end;

  • Palladin © (14.11.08 20:21) [19]
    :) да нашел я эти 3, ушедших на резалт, первый строчка и второй строчка, указателя, сидевших до end для обработчика события :)
  • Mystic © (14.11.08 20:59) [20]
    Честно говоря я тоже какое-то время ломал себе голову над тем, откуда там утечка, но по другой причине. В коде строкам в программе присваиваются литеральные значения (за исключением экземпляра типа TStringList, но он уже к нужному моменту уничтожается). Следовательно все переменные типа string должны указывать на образ файла, и RefCount = $FFFFFFFF. Однако оказалось, что при вызове @LStrAsg все-таки происходит динамическое выделение памяти, даже если source литеральная строка. Впрочем понятный коментарий в этой функции объясняет и причину, по которой так сделано: чтобы исключить AV в случае динамической выгрузки пакета и/или DLL. С другой стороны осталось загадкой, почему компилятор поставил на операторе
    Result := def

    вызов @LStrAsg, а не @LStrLAsg, ведь Result это не глобальная переменная...
  • Mystic © (14.11.08 21:22) [21]
    Впрочем и это понятно :) Поскольку в операторе используется Result, и фиг его знает, какой переменной будет присвоено значение функции (глобальной или локальной), то закладываться надо на самый худший вариант.
  • Palladin © (14.11.08 22:28) [22]

    > Впрочем и это понятно :)

    ага, уже потом.. )))
 
Конференция "Прочее" » Exit внутри Try/Finally [D6, XP]
Есть новые Нет новых   [134446   +31][b:0][p:0.002]