Конференция "Основная" » какие накладные расходы у try except end?
 
  • Jolik © (28.03.08 15:50) [0]
    Господа!

    Может ли кто просветить (хотя бы оценочно) насколько функция с try except end медленне функции без нее в случае НЕвозникновения исключения.
    Ведь компилятор делает какие-то телодвижения при входе в процедуру если там есть блок try except end? Да и при выходе наверное...

    Заранее благодарен!
  • Kolan © (28.03.08 15:51) [1]
    CPU Window посмотри и ответь себе сам.
  • Сергей М. © (28.03.08 15:59) [2]

    > компилятор делает какие-то телодвижения при входе в процедуру
    > если там есть блок try except end? Да и при выходе наверное


    Угу.
    И совсем небольшие. Если, конечно же, не учитывать соотв.телодвижения системы.

    Если это критично, то ты либо должен быть асом либо авантюристом)
  • Thrasher © (28.03.08 16:59) [3]
    Разница всего в парочку ассемблерных инструкций.

    xor eax,eax  //только когда есть try, except
    push ebp
    push Adddr //только когда есть try, except
    push dword ptr fs:[eax] //только когда есть try, except
    mov fs:[eax],esp //только когда есть try, except

    //текст процедурі, где может возникнуть исключение

    mov fs:[eax],edx //только когда есть try, except
    jmp +$A //только когда есть try, except
    Addr:
    jmp Exception //только когда есть try, except

    Call DoneExcept //только когда есть try, except




    Потом вычисляем сколько тактов заберут инструкции. И узнаем сколько "лишнего" времени съел процессор.
  • Jolik © (28.03.08 17:13) [4]
    Исчерпывающе.
    Спасибо!
  • Тыщ (04.04.08 09:10) [5]
    Кстати, может, кто-нибудь знает, почему в функции и процедуры, содержащие работу со строками, автоматически добавляется обработка исключений, и как этого избежать (ну, кроме переписывания кода на ассемблере)?
  • Тыщ (04.04.08 09:14) [6]
    Прошу прощения, не содержащие, а вызывающие другие функции, возвращающие строку.

    Пример:
    function ExpandEnvironmentStrings2(const s:string):string;
    var Buffer:pchar;
       Size:cardinal;
    begin
     Size:=ExpandEnvironmentStrings(pchar(s),nil,0);
     GetMem(Buffer,Size);
     Size:=ExpandEnvironmentStrings(pchar(s),Buffer,Size);
     SetString(Result,Buffer,Size-1);
     FreeMem(Buffer);
    end;

    begin
     // Тут как будто есть блок try..except..end
     ExpandEnvironmentStrings2('%PATH%');
    end.

  • Сергей М. © (04.04.08 09:14) [7]

    > почему в функции и процедуры, содержащие работу со строками,
    >  автоматически добавляется обработка исключений


    С чего ты взял ?
  • Тыщ (04.04.08 09:17) [8]
    Сергей М. ©   (04.04.08 9:14) [7]

    > С чего ты взял ?

    Дизассемблер показывает.
  • Сергей М. © (04.04.08 09:22) [9]

    > Тыщ   (04.04.08 09:17) [8]


    Ну если возвращаемое значение есть LargeString, то это вполне объяснимо - это тип данных с управляемым временем жизни.
  • Тыщ (04.04.08 09:28) [10]
    Сергей М. ©   (04.04.08 9:22) [9]

    Ну так эта обработка и висит мертвым грузом. Управляемое время жизни тут причем? Оно управляется LStrFromPCharLen и LStrClr в моем случае, в них обработки исключений никакой нет.
  • Тыщ (04.04.08 09:30) [11]
    Если вырезать обработку исключений ручками, то код работает так же.
    Вопрос в том, как это убрать во время компиляции.
  • Сергей М. © (04.04.08 09:31) [12]

    > эта обработка и висит мертвым грузом


    Угу, висит.
    До тех пор пока дело не закончится исключением.


    > Управляемое время жизни тут причем?


    А ты спровоцируй искл.ситуацию при исполнении этой ф-ции и посмотри, куда уходит обработка исключнения и что реально полезного она при этом делает !
  • Тыщ (04.04.08 09:35) [13]
    Сергей М. ©   (04.04.08 9:31) [12]

    Это-то понятно, но я пишу на чистом WinAPI без обработки исключений, где надо, там сам обработку поставлю, а тут самодеятельность компилятора только раздражает.
  • Сергей М. © (04.04.08 09:39) [14]

    > пишу на чистом WinAPI без обработки исключений
    > самодеятельность компилятора только раздражает


    Ну так и пиши без использования типов с управляемым временем жизни, в чем проблема-то ?)
  • Тыщ (04.04.08 09:41) [15]
    Сергей М. ©   (04.04.08 9:39) [14]

    Без строк, с pchar'ами плохо и неудобно :(
  • Сергей М. © (04.04.08 09:42) [16]

    > плохо и неудобно


    Тогда забудь про "чистый WinAPI", в чем проблема-то ?)
  • Тыщ (04.04.08 09:42) [17]
    Может, можно как-нибудь обмануть компилятор, чтобы не добавлял обработку исключений?
  • Сергей М. © (04.04.08 09:45) [18]
    Не надо его обманывать, он все равно умнее тебя)
  • Тыщ (04.04.08 09:47) [19]
    Сергей М. ©   (04.04.08 9:45) [18]

    > он все равно умнее тебя)

    С чего это?
  • Сергей М. © (04.04.08 09:48) [20]
    Впрочем, если геморрой на собственный зад тебя не страшит, готовь данные и вызывай функции с использованием basm, тогда компилятор махнет на твои извращения рукой)
  • Сергей М. © (04.04.08 09:49) [21]

    > С чего это?


    Он мне по секрету на ушко шепнул)
  • Тыщ (04.04.08 09:51) [22]
    Сергей М. ©   (04.04.08 9:48) [20]

    О чем и говорилось в [5]:
    > кроме переписывания кода на ассемблере

    Сергей М. ©   (04.04.08 9:49) [21]

    Ну-ну...
  • Сергей М. © (04.04.08 09:56) [23]

    > О чем и говорилось в [5]


    В [5] не было конкретностей, они появились в [6].

    А вот теперь измени декларацию своей ф-ции на следующую процедуру:

    procedure ExpandEnvironmentStrings2(var s:string);



    Удивись - компилятор не заключил вызов процедуры в try-блок !

    Теперь думай над происходящим)
  • Тыщ (04.04.08 10:06) [24]
    Сергей М. ©   (04.04.08 9:56) [23]

    Честно удивлюсь, если не заключил. У меня заключил.

    Код:
    uses Windows;
    {$APPTYPE CONSOLE}
    procedure ExpandEnvironmentStrings2(var s:string);
    var Buffer:pchar;
       Size:cardinal;
    begin
     Size:=ExpandEnvironmentStrings(pchar(s),nil,0);
     GetMem(Buffer,Size);
     Size:=ExpandEnvironmentStrings(pchar(s),Buffer,Size);
     SetString(s,Buffer,Size-1);
     FreeMem(Buffer);
    end;

    procedure Write_(var s:string);
    var Temp:dword;
    begin
     WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),s[1],Length(s),Temp,nil);
    end;

    var
     s:string;
    begin
     s:='%PATH%';
     ExpandEnvironmentStrings2(s);
     Write_(s);
    end.

  • Сергей М. © (04.04.08 10:10) [25]

    > У меня заключил


    Врешь и не моргаешь)
    Или не понимаешь в принципе, какому конкретно программному действию этот блок соответствует.
  • Тыщ (04.04.08 10:19) [26]
    Сергей М. ©   (04.04.08 10:10) [25]

    >> У меня заключил
    > Врешь и не моргаешь)

    Смотрю в самое начало кода и вижу
    mov fs:[eax],esp

    . Кто врет?

    > Или не понимаешь в принципе, какому конкретно программному действию этот блок соответствует.

    Случай,
    > если возвращаемое значение есть LargeString
    мы убрали, в каких еще случаях генерируется этот блок?
    Не затруднит рассказать или хотя бы дать ссылку?
  • Сергей М. © (04.04.08 10:28) [27]

    > Смотрю в самое начало кода и вижу mov fs:[eax],esp . Кто
    > врет?


    ты, разумеется)

    Этот блок появился по факту присутствия строчки

    s:='%PATH%'



    но отнюдь не строчки

    ExpandEnvironmentStrings2(s);



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


    > в каких еще случаях генерируется этот блок?


    Во всех случаях когда компилятор берет на себя ответственность за безусловное освобождение ресурсов, распределенных под данные с управляемым временем жизни, при потенциальной возможности исключений.
  • Тыщ (04.04.08 10:43) [28]
    Сергей М. ©   (04.04.08 10:28) [27]

    Нет, виновата строка с var:

    var s:string;
    begin
    end.



    Даже тут генерируется этот блок...

    Спасибо за объяснение.

    Итак, строку можно вернуть либо функцией, либо процедурой с var string.
    В обоих случаях будет генерироваться этот блок.

    Есть ли еще способы вернуть строку (AnsiString)?
  • Сергей М. © (04.04.08 10:54) [29]

    > виновата строка с var


    Далеко не всегда.


    > В обоих случаях будет генерироваться этот блок


    Вовсе не факт.
  • Сергей М. © (04.04.08 10:56) [30]
    var
     s: string;

    procedure TForm1.Button2Click(Sender: TObject);
    begin
     s := '%PATH%';
    end;

    Удивись - никаких блоков компилятор не сгенерировал.
  • Тыщ (04.04.08 10:56) [31]
    Сергей М. ©   (04.04.08 10:54) [29]

    Приведите пример, пожалуйста.
  • Сергей М. © (04.04.08 10:58) [32]
    см. [30]
  • Тыщ (04.04.08 10:58) [33]
    Сергей М. ©   (04.04.08 10:56) [30]

    Ну да, в функции
    TForm1.Button2Click

    не будет этого блока, а в главном
    begin end.

    все равно будет.
  • Сергей М. © (04.04.08 11:03) [34]

    > в главном begin end. все равно будет


    И чем он тебе помешал ?
    Этот блок "охватит" всю работу приложения, один раз за всю его жизнь, что никак не отразится на сквозной его производительности.
  • Тыщ (04.04.08 11:07) [35]
    Сергей М. ©   (04.04.08 11:03) [34]

    > И чем он тебе помешал ?

    Давайте все-таки отвечать на заданный вопрос - "как избавиться от блока обработки исключений", а не такой вопрос - "чем тебе мешает X?"
    Если бы он мне не мешал, я бы не задавал свой вопрос, логично?
  • Сергей М. © (04.04.08 11:13) [36]
    Отвечаю - не пользовать конструкции вида [28].
  • Сергей М. © (04.04.08 11:15) [37]
    Нелогично другое - стремление к блохоловству, аргументированное лишь ничего не значащим "пишу на чистом ВинАПИ"
  • Сергей М. © (04.04.08 11:19) [38]
    Ты объясни, на чем ты хочешь сэкономить, избавившись от сабжа ?
    На размере исп.модуля ?
    На локальной/сквозной производительности приложения ?
  • clickmaker © (04.04.08 11:23) [39]

    > [35] Тыщ   (04.04.08 11:07)

    уверен, что жонглирование нуль-терминированными строками, с постоянным перераспределением памяти компенсирует избавление от исключений?
    готов написать свой более оптимальный менеджер памяти, чем борландовый?
  • Тыщ (04.04.08 11:23) [40]
    Сергей М. ©   (04.04.08 11:19) [38]

    В программе должно быть все красиво - и размер, и скорость, и структура, внешняя и внутренняя.
    Не должно быть ничего лишнего.
    Если программирование искусством считать, конечно.
    А для себя я считаю именно так.
  • Тыщ (04.04.08 11:27) [41]
    clickmaker ©   (04.04.08 11:23) [39]

    Как раз таки я и пытаюсь жонглировать паскалевскими строками, а не нуль-терминированными.
    Использую встроенный в Windows менеджер памяти (HeapAlloc, HeapFree), он не вызывает исключения, если его специально не просить.
  • Сергей М. © (04.04.08 11:30) [42]

    > В программе должно быть все красиво


    У тебя искаженные представления о красоте.


    > Не должно быть ничего лишнего


    Не пользуйся типами данных с управляемым временем жизни - не будет ничего лишнего.
    Но и не хнычь при этом, мол, "pchar не хочу, асм тоже не хочу, хочу длинные строки, че за фигню мне впаривает компайлер")
  • Сергей М. © (04.04.08 11:32) [43]

    > пытаюсь жонглировать паскалевскими строками


    А как же насчет "ничего лишнего" ?
    Ведь длинные длинные строки содержат "лишний заголовок" !)
    Как же ты с этим миришься при таких амбициях ?)
  • Сергей М. © (04.04.08 11:34) [44]
    Понимаешь ли, создавать свою красоту резонно лишь полностью постигнув чужую)
  • Тыщ (04.04.08 11:34) [45]
    Сергей М. ©   (04.04.08 11:32) [43]

    > Ведь длинные длинные строки содержат "лишний заголовок" !)

    Их размер что-ли? Так это наоборот очень хорошо - во-первых, в них можно хранить любые бинарные данные, а во-вторых, не нужно пробегать по всей строке, чтобы вычислить длину.
  • Сергей М. © (04.04.08 11:44) [46]

    > Тыщ   (04.04.08 11:34) [45]


    > в них можно хранить любые бинарные данные


    Ты их и в нуль-терминированной строке хранить можешь, ничто этому не препятствует.

    Там еще и сч-к имеется, а к работе со сч-ками (и не только с ним) тебе прилагается довольно увесистый "джентльменский набор" подпрограмм в составе system.pas.

    Если тебе не понадобится львиная доля этих п/программ, то как насчет красоты, притом что они будут фигурировать в твоем исп.модуле мертвым грузом ?)
  • Тыщ (04.04.08 11:48) [47]
    Сергей М. ©   (04.04.08 11:44) [46]

    > Ты их и в нуль-терминированной строке хранить можешь, ничто этому не препятствует.

    Встретится там #0, и обрежет строку.

    > ...

    Вы не правы, из "джентльменского набора" исключаются все неиспользуемые функции и не будут мертвым грузом.
  • clickmaker © (04.04.08 11:52) [48]

    > Встретится там #0, и обрежет строку.

    зависит от того, кто встретит
  • Сергей М. © (04.04.08 11:54) [49]

    > Встретится там #0, и обрежет строку


    Чавой-то ?!

    Какая такая "обрежет", если ты сознательно работаешь с буфером строки как с областью памяти, содержащей произвольные бин.данные ?


    > Вы не правы


    Где аргументы ?)
  • Тыщ (04.04.08 12:01) [50]
    Сергей М. ©   (04.04.08 11:54) [49]

    > Какая такая "обрежет", если ты сознательно работаешь с буфером строки как с областью памяти, содержащей произвольные бин.данные ?

    Буфер - это уже не нуль-терминированная строка, и размер его вычисляется не позицией #0.

    >> исключаются все неиспользуемые функции
    > Где аргументы ?)

    var s:string;
    begin
     s:='Test';
    end.



    program.map:

     Address         Publics by Value

    0001:00000000       @GetMem
    0001:00000010       @FreeMem
    0001:00000020       Move
    0001:00000080       @LStrAsg
    0001:000000C4       @NewAnsiString
    0001:000000F0       ExitProcess
    0001:000000F8       GetProcessHeap
    0001:00000100       HeapAlloc
    0001:00000108       HeapFree
    0001:00000110       System
    0001:00000114       SysInit
    0001:00000138       PROGRAM
    0002:00001000       s

  • Тыщ (04.04.08 12:02) [51]
    Естественно, я использую свои собственные System.pas и Sysinit.pas.
  • Сергей М. © (04.04.08 12:09) [52]

    > размер его вычисляется не позицией #0


    А кто тебя заставляет пользоваться п/программами, занимающимися именно  таким вычислением ?


    > program.map


    И где здесь аргумент, отрицающий факт присутствия в образе исп.модуля машкода, соответствующего, например, ф-ции _IntfClear ?
  • Сергей М. © (04.04.08 12:14) [53]

    > я использую свои собственные System.pas и Sysinit.pas


    И при этом компилятор упорно вставляет блок и все работает ?
    Даже если в покоцаном system нет ни намека на п/п HandleFinally ?

    Чудеса)

    Впрочем, покоцал исп.модуль ты сам, а не компилятор.
    Компилятор честно включил весь машкод сист.юнитов в будущий объектный код)
  • Сергей М. © (04.04.08 12:16) [54]

    > будущий


    Это я сморозил.
  • Тыщ (04.04.08 12:17) [55]
    Сергей М. ©   (04.04.08 12:09) [52]

    > А кто тебя заставляет пользоваться п/программами, занимающимися именно  таким вычислением ?

    Давайте закончим обсуждение нуль-терминированных строк на том, что в нуль-терминированной строке нельзя хранить бинарные данные, содержащие нули.

    > И где здесь аргумент, отрицающий факт присутствия в образе исп.модуля машкода, соответствующего, например, ф-ции _IntfClear ?

    В program.map перечислены все используемые функции и переменные.
    Вам exe-шник показать?
  • Сергей М. © (04.04.08 12:21) [56]

    > Тыщ   (04.04.08 12:17) [55]



    > exe-шник показать?


    Ага.
    И исх.текст system.pas.
  • Тыщ (04.04.08 12:21) [57]
    Сергей М. ©   (04.04.08 12:14) [53]

    >И при этом компилятор упорно вставляет блок и все работает ?
    >Даже если в покоцаном system нет ни намека на п/п HandleFinally ?

    В System.pas нигде нет конструкции, отвечающей именно за блоки обработки исключений. Она защита где-то в компиляторе, то есть, в dcc32.exe.
  • Сергей М. © (04.04.08 12:31) [58]

    > Она защита где-то в компиляторе


    Да ты что ?!

    А мужики-то и не знали)

    И это они сами придумали:


    procedure       _HandleFinally;
    asm
    {$IFDEF PC_MAPPED_EXCEPTIONS}
    {$IFDEF PIC}
           MOV     ESI, EBX
    {$ENDIF}
           CMP     ECX, UW_EXC_CLASS_BORLANDCPP    // C++ exception?
           JNE     @@handleIt                      // nope, handle it
           // unwinding a C++ exception.  We handle that specially.
           PUSH    EAX
           PUSH    EDX
           PUSH    ECX
           MOV     EDX, [ESP+12]
           CALL    EDX
           POP     ECX
           POP     EDX
           POP     EAX
           CALL    SysRaiseCPPException

    @@handleIt:
           PUSH    EAX
           PUSH    EDX
           CALL    UnblockOSExceptions
           POP     EDX
           POP     EAX

           // If the exception is a Delphi exception thrown from C++, coopt it.
           CALL    MaybeCooptException

           MOV     EDX, [ESP]
           CALL    NotifyExceptFinally
           PUSH    EAX
    {$IFDEF PIC}
           MOV     EBX, ESI
    {$ENDIF}
           {
             Mark the current exception with the EBP of the handler.  If
             an exception is raised from the finally block, then this
             exception will be orphaned.  We will catch this later, when
             we clean up the next except block to complete execution.
             See DoneExcept.
           }

           MOV [EAX].TRaisedException.HandlerEBP, EBP
           CALL    EDX
           POP     EAX
           {
             We executed the finally handler without adverse reactions.
             It's safe to clear the marker now.
           }

           MOV [EAX].TRaisedException.HandlerEBP, $FFFFFFFF
           PUSH    EBP
           MOV     EBP, ESP
           CALL    SysRaiseException             // Should be using resume here
    {$ENDIF}
    {$IFDEF MSWINDOWS}
           { ->    [ESP+ 4] excPtr: PExceptionRecord       }
           {       [ESP+ 8] errPtr: PExcFrame              }
           {       [ESP+12] ctxPtr: Pointer                }
           {       [ESP+16] dspPtr: Pointer                }
           { <-    EAX return value - always one   }

           MOV     EAX,[ESP+4]
           MOV     EDX,[ESP+8]
           TEST    [EAX].TExceptionRecord.ExceptionFlags,cUnwindInProgress
           JE      @@exit
           MOV     ECX,[EDX].TExcFrame.desc
           MOV     [EDX].TExcFrame.desc,offset @@exit

           PUSH    EBX
           PUSH    ESI
           PUSH    EDI
           PUSH    EBP

           MOV     EBP,[EDX].TExcFrame.hEBP
           ADD     ECX,TExcDesc.instructions
           CALL    NotifyExceptFinally
           CALL    ECX

           POP     EBP
           POP     EDI
           POP     ESI
           POP     EBX

    @@exit:
           MOV     EAX,1
    {$ENDIF}
    end;

  • Тыщ (04.04.08 12:36) [59]
    Сергей М. ©   (04.04.08 12:21) [56]

    >> exe-шник показать?
    >Ага.

    http://tysch.narod.ru/test10.zip

    System.pas пока что не могу показать.

    Сергей М. ©   (04.04.08 12:31) [58]

    Ткните меня носом, где написано
    mov fs:[eax],esp

    , пожалуйста.
  • Сергей М. © (04.04.08 12:47) [60]

    > System.pas пока что не могу показать


    А без него сравнение бессмысленно.
    Так что будем пока считать твои утверждения голословными)


    > где написано mov fs:[eax],esp


    Причем здесь это ? Это само собой.

    Я про код финализации защищаемого блока, обращение к которому компилятор обязательно будет пытаться вставить в результ.код.

    А к чему обращаться-то, если ты покоцал system и выкорчевал оттуда все непонятное и посему якобы ненужное ?)
  • Игорь Шевченко © (04.04.08 13:01) [61]

    > Причем здесь это ? Это само собой.


    Это не само собой. Это именно то, что делает компилятор при встрече конструкции try...{finally|except} - вставляет формирование блока обработки исключительной ситуации - N команд в начале блока, N команд в конце.
  • Тыщ (04.04.08 13:01) [62]
    Сергей М. ©   (04.04.08 12:47) [60]

    > Причем здесь это ? Это само собой.
    > Я про код финализации защищаемого блока, обращение к которому компилятор обязательно будет пытаться вставить в результ.код.

    А причем здесь код финализации? Я про него вообще не говорил.
    Я говорил про блок обработки исключений, а он зашит в компиляторе. С чем не согласны?

    http://tysch.narod.ru/test11.zip
    Вот, убедитесь, никакого _IntfClear там нет.
  • Сергей М. © (04.04.08 13:11) [63]

    > Я про него вообще не говорил.
    > Я говорил про блок обработки исключений


    Да мало ли что там еще "зашито")


    > http://tysch.narod.ru/test11.zip


     403  
    Нет главной страницы

    Ой
    В разделе сайта, к которому вы обратились, нет главной страницы
  • Тыщ (04.04.08 13:15) [64]
    Сергей М. ©   (04.04.08 13:11) [63]

    Не надо, а? Все отлично открывается.
  • Сергей М. © (04.04.08 13:15) [65]

    > Игорь Шевченко ©   (04.04.08 13:01) [61]


    А никто и не возражает, даже если это неявный try-блок
  • Сергей М. © (04.04.08 13:22) [66]

    > Тыщ   (04.04.08 13:15) [64]


    ну любуйся сам, раз открывается)

    Помощь вообще-то  тебе нужна, а не мне)
  • Тыщ (04.04.08 13:27) [67]
    Сергей М. ©   (04.04.08 13:22) [66]

    Я сомневаюсь, что ссылка не работает - другу дал проверить, работает.
    Есть другие предложения, как вам этот файл передать?
  • Сергей М. © (04.04.08 13:28) [68]
    slil.ru

    Кидай туда - и 1-ю и 2-ю (обе не открываются)
  • Eraser © (04.04.08 13:32) [69]

    > Тыщ   (04.04.08 11:23) [40]
    > Сергей М. ©   (04.04.08 11:19) [38]В программе должно быть
    > все красиво - и размер, и скорость, и структура, внешняя
    > и внутренняя.Не должно быть ничего лишнего.Если программирование
    > искусством считать, конечно.

    потому и не надо изобретать велосипды.

    сочувствую человеку, который будет разбираться в этом коде потом..
    видал я тварения таких любителей красоты, блин..

    код должен быть красив и по-возможности решать задачу, для выполнения которой и написана программа, а не выполнять обслуживающие действия, для которых как раз и придуман VCL.
  • Eraser © (04.04.08 13:34) [70]

    > Тыщ   (04.04.08 13:27) [67]

    не работает.
  • Сергей М. © (04.04.08 13:35) [71]

    > Eraser ©   (04.04.08 13:34) [70]
    >
    >


    Значит ты не друг)
  • Тыщ (04.04.08 13:36) [72]
    Сергей М. ©   (04.04.08 13:28) [68]

    http://slil.ru/25652671
  • palva © (04.04.08 13:41) [73]

    > > Тыщ   (04.04.08 13:27) [67]
    Narod не хочет отдавать файл, отмазывается, что в разделе нет главной страницы.
  • Тыщ (04.04.08 13:42) [74]
    palva ©   (04.04.08 13:41) [73]

    А она там есть, index.html.
  • Сергей М. © (04.04.08 14:09) [75]

    > Тыщ


    Так.
    Посмотрел.

    Все верно - ты покоцал тела всех п/программ, относящихся к сабжу, после чего скомпилил юнит. В результате объектный код таких п/программ в system.dcu превратился в одну-единственную инструкцию RETN.

    При компиляции проекта компилятор справедливо заменил инструкцию вызова таких "затычек" на непосредственно инструкцию RETN.

    Т.е. ты поменял шило на мыло)
  • Тыщ (04.04.08 14:16) [76]
    Сергей М. ©   (04.04.08 14:09) [75]

    Ну, убедились, что _IntfClear там нет?

    От "затычек" я избавился (от большинства) в test10.
    Вопрос прежний -
    > Есть ли еще способы вернуть строку (AnsiString)?
  • Сергей М. © (04.04.08 14:17) [77]
    Маньяк !)

    Начисто выбрил весь код, имеющий отношение к SEH, но при этом оставил огромную кучу "хлама", явно не требуемого при "пишу на чистом ВинАПИ"

    ))
  • Тыщ (04.04.08 14:18) [78]
    Сергей М. ©   (04.04.08 14:17) [77]

    > оставил огромную кучу "хлама"

    Например?
  • Сергей М. © (04.04.08 14:20) [79]

    > Тыщ   (04.04.08 14:16) [76]


    > убедились, что _IntfClear там нет?


    Ну ты и фрукт)

    На момент, когда я упомянул _IntfClear, предполагалось что ты пользуешь штатный system.dcu, а не выбритый лоскутами)
  • Сергей М. © (04.04.08 14:22) [80]

    > Например?


    Дык тот же TObject и иже с ним потроха занимают немало места !
    Некузяво как-то) .. Выбрей и его тож)
  • Тыщ (04.04.08 14:25) [81]
    Сергей М. ©   (04.04.08 14:20) [79]

    > На момент, когда я упомянул _IntfClear, предполагалось что ты пользуешь штатный system.dcu, а не выбритый лоскутами)

    Странно, добавил _IntfClear в System.pas, а он все равно не прикомпилировался.

    Сергей М. ©   (04.04.08 14:22) [80]

    > Дык тот же TObject и иже с ним потроха занимают немало места !

    Только в system.pas, не в конечной программе, если не используется.
  • Сергей М. © (04.04.08 14:41) [82]

    > Странно, добавил _IntfClear в System.pas, а он все равно
    > не прикомпилировался


    Странно, я заведомо использую блоки try..finally
    c заведомо штатным system.dcu, а в map'е процедурой идентификатором _HandleFinally даже не пахнет.

    Наверно тоже не "прикомпилировался")

    Вот ведь чудеса в решете - кода нет, а он успешно работает)
  • Тыщ (04.04.08 14:51) [83]
    Сергей М. ©   (04.04.08 14:41) [82]

    > в map'е процедурой идентификатором _HandleFinally даже не пахнет.

    @HandleFinally там есть.
  • Тыщ (04.04.08 14:58) [84]
    Во, обработку исключений победил!

    uses Windows;
    {$APPTYPE CONSOLE}

    procedure LStrFromPCharLen(Dest: PAnsiString; Source: PAnsiChar; Length: Integer);
    asm
     jmp System.@LStrFromPCharLen
    end;

    procedure LStrClr(S:PAnsiString);
    asm
     jmp System.@LStrClr
    end;

    procedure ExpandEnvironmentStrings2(var s:string);
    var Buffer:pchar;
       Size:cardinal;
    begin
     Size:=ExpandEnvironmentStrings(pchar(s),nil,0);
     GetMem(Buffer,Size);
     Size:=ExpandEnvironmentStrings(pchar(s),Buffer,Size);
     SetString(s,Buffer,Size-1);
     FreeMem(Buffer);
    end;

    procedure Write_(var s:string);
    var Temp:dword;
    begin
     WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),s[1],Length(s),Temp,nil);
    end;

    var
     s:pstring;
     s_holder:integer;
    begin
     s:=@s_holder;
     LStrFromPCharLen(s,'%PATH%',6);
     ExpandEnvironmentStrings2(s^);
     Write_(s^);
     LStrClr(s);
    end.

  • Сергей М. © (04.04.08 15:01) [85]

    > @HandleFinally там есть.


    Согласен, есть.

    Но точно также там не будет никакого кода, касаемого обработки исключений, если ты не спровоцируешь его появление.
  • Сергей М. © (04.04.08 15:05) [86]
    Если такого "красивого" исх.кода будет эдак мегабайт на 10..20 и там вкрадется лог.ошибка, тот, кто будет вынужденно изучать твой код с целью исправления этой ошибки, обязательно поймайт и поколотит тебя)

    А ошибка там обязательно будет)
  • Тыщ (04.04.08 15:09) [87]
    Ничего, с pchar'ами не лучше.
  • Игорь Шевченко © (04.04.08 15:10) [88]
    Дети Ивана Кулибина.
  • Сергей М. © (04.04.08 15:34) [89]

    > Ничего, с pchar'ами не лучше


    Угу.
    Лучше, наверно, нарваться на исключение и игнорировать этот факт (как и саму обработку), пребывая в святой уверенности, что операция прошла успешно)


    > procedure ExpandEnvironmentStrings2(var s:string);
    > var Buffer:pchar;
    >    Size:cardinal;
    > begin
    >  Size:=ExpandEnvironmentStrings(pchar(s),nil,0);
    >  GetMem(Buffer,Size); //а если память по каким-то причинам не была выделена ?
    >  Size:=ExpandEnvironmentStrings(pchar(s),Buffer,Size); //в buffer'е мусор, это спровоцирует иск.ситуацию
    >  SetString(s,Buffer,Size-1); //даже если GetMem выполнена успешно, аллокация памяти под строку и копирование туда данных из буфера тоже может завершиться неуспехом ?
    >  FreeMem(Buffer); //если в buffer'е не мусор, то произойдет утечка памяти, поскольку при обработке искл-я у тебя происходит банальный выход по RETN
    > end;
    >
  • Сергей М. © (04.04.08 15:36) [90]

    > Дети Ивана Кулибина


    Да уж ...
    SEH для них - просто ненужный мусор)
  • Тыщ (04.04.08 15:39) [91]
    Сергей М. ©   (04.04.08 15:34) [89]

    Если системе будет настолько нехватать памяти, что моя программа не сможет выделить сотню-другую байт, то система при этом явно уже будет рушиться и без моей программы.
  • Тыщ (04.04.08 15:40) [92]
    Сергей М. ©   (04.04.08 15:36) [90]

    SEH на каждый чих - мусор, вот :)
  • Сергей М. © (04.04.08 15:48) [93]

    > Если системе будет настолько нехватать памяти


    А с чего ты взял, что операция аллокации может вызвать искл-е только по этой причине ?)


    > SEH на каждый чих - мусор


    Зачем на каждый ?
    Вовсе не обязательно)

    Но обернуть весь код хотя бы в один блок, чтобы пощадить глаза и мозг юзера от тарабарщины в системных сообщениях о необработанных тобой исключениях - разве это не истинная "красота" программы ?

    Я уже не говорю о ситуации, когда бедный юзер материт такого вот горе-разработчика, чья программа после запуска тут же тихо умирает, не подав никакие признаки рождения)
  • Тыщ (04.04.08 15:58) [94]
    Сергей М. ©   (04.04.08 15:48) [93]

    > с чего ты взял, что операция аллокации может вызвать искл-е только по этой причине ?)

    По какой же еще?

    > программа после запуска тут же тихо умирает

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

    The instruction at "0x00401080" referenced memory at "0x00000000". The memory could not be "read".

    Click on OK to terminate the program
    Click on CANCEL to debug the program

  • Сергей М. © (04.04.08 16:10) [95]

    > По какой же еще?


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

    Да мало ли в бразилии Педро !)


    > получим стандартное и вполне приличное


    Очень прилично, нечего сказать)
    Для какой-нить главбухши, знающий только "дебеты-кредиты-сальды-сторны" - самое то)
  • Тыщ (05.04.08 11:39) [96]
    Сергей М. ©   (04.04.08 16:10) [95]

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

    Да уж, это надо постараться...

    > Для какой-нить главбухши, знающий только "дебеты-кредиты-сальды-сторны" - самое то)

    Для "какой-нить главбухши" я не пишу... пока что.
  • Mystic © (07.04.08 18:24) [97]
    > Во, обработку исключений победил!

    При работе со строками большую часть ресурсов заберет не несколько ассемблерных инструкций + 12 байт стека + обращение к TEB, а использование динамической памяти. И победа далась тебе дорогой ценой: вставлено несколько дополнительных вызовов CALL и JMP. Можешь сравнить эти два фрагмента по скорости ;)
  • Сергей М, (07.04.08 20:44) [98]

    > Mystic ©   (07.04.08 18:24) [97]


    Красота требует жертв)
    Автору все это фиолетово - главное чтобы было  "красиво")
  • oxffff © (07.04.08 21:06) [99]

    > Тыщ   (04.04.08 14:58) [84]
    > Во, обработку исключений победил!


    Кто? Где?
  • Сергей М, (07.04.08 21:10) [100]

    > Кто? Где?


    Опоздал)
    Ордена Сутулова уже раздали)
  • oxffff © (07.04.08 21:15) [101]

    > Сергей М,   (07.04.08 21:10) [100]
    >
    > > Кто? Где?
    >
    >
    > Опоздал)
    > Ордена Сутулова уже раздали)


    А зачем
    procedure LStrClr(S:PAnsiString);
    asm
    jmp System.@LStrClr
    end;

    LStrClr(s);

    Что S^:='' не поможет в случае гарантированной инициализации S? :)
  • Тыщ (08.04.08 17:17) [102]
    oxffff ©   (07.04.08 21:15) [101]

    А, ну да,
    s^:=''

    сделает вызов
    LStrClr

    напрямую.
 
Конференция "Основная" » какие накладные расходы у try except end?
Есть новые Нет новых   [134484   +49][b:0.001][p:0.007]