On 02.02.2023 07:42, Sven Barth via fpc-devel wrote:
The case when you *need* a constant reference. Case in point: the passing of TGuid in IInterface.QueryInterface. Delphi code relies on it being a reference, but “const” does not guarantee that for all platforms.

Maybe I am missing something, could you please explain why IInterface.QueryInterface needs constref?

Delphi definition doesn't use it (Delphi 11):

  IInterface = interface
    ['{00000000-0000-0000-C000-000000000046}']
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  end;

FPC uses it in the definition:

       IUnknown = interface
         ['{00000000-0000-0000-C000-000000000046}']
         function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};          function _AddRef : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};          function _Release : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
       end;

but when I check all the implementations of QueryInterface in objpas.inc I see that the iid is paased to TObject.QueryInterface

      function TObject.GetInterface(const iid : tguid;out obj) : boolean;

that has a const without ref.

---

I myself cannot think of any real use case of constref other than hacks like the FreeAndNil in recent Delphi versions:

procedure FreeAndNil(const [ref] Obj: TObject);

that needs the ref because it changes it to nil (so is not really a const - it used to be an untyped var). As a result FreeAndNil allows you to happily pass read-only properties to it that are then nilled.

Maybe somebody knows a real use case?

Ondrej

_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to