string := const : why different implementation for local and result?

后端 未结 2 488
情书的邮戳
情书的邮戳 2021-01-12 01:01

In Delphi function result is frequently implemented as var-parameter (not out-parameter despite QC ticket).

String constants are basically variables with negative re

2条回答
  •  难免孤独
    2021-01-12 01:27

    In Delphi, constant strings are always copied when assigned to another global variable, but not to a local variable, to avoid access violation in some borderline cases.

    Use the source, Luke!

    See this code extraction from System.pas:

    { 99.03.11
      This function is used when assigning to global variables.
    
      Literals are copied to prevent a situation where a dynamically
      allocated DLL or package assigns a literal to a variable and then
      is unloaded -- thereby causing the string memory (in the code
      segment of the DLL) to be removed -- and therefore leaving the
      global variable pointing to invalid memory.
    }
    procedure _LStrAsg(var dest; const source);
    var
      S, D: Pointer;
      P: PStrRec;
      Temp: Longint;
    begin
      S := Pointer(source);
      if S <> nil then
      begin
        P := PStrRec(Integer(S) - sizeof(StrRec));
        if P.refCnt < 0 then   // make copy of string literal
        begin
          Temp := P.length;
          S := _NewAnsiString(Temp);
          Move(Pointer(source)^, S^, Temp);
          P := PStrRec(Integer(S) - sizeof(StrRec));
        end;
        InterlockedIncrement(P.refCnt);
      end;
    ....
    

    So in short, by design, and to avoid access violations when a DLL or package is unloaded and did contain some constant values sent back to the main process, a local copy is always made.

    You have two functions:

    • LStrAsg or UStrAsg which is generated by the compiler when a string has a chance to be a constant - this is the code above;
    • LStrLAsg or UStrLAsg (added L stands for "local") which is generated by the compiler when the source string is local, so has no be a constant: in this case, P.refCnt < 0 won't be checked, so it will be faster than upper code.

提交回复
热议问题