[fpc-devel] constref in Windows

Joost van der Sluis joost at cnoc.nl
Fri Nov 19 13:02:59 CET 2010


On Fri, 2010-11-19 at 12:39 +0100, José Mejuto wrote:
> Hello FPC,
> 
> In fpc 2.5.1 trunk today the QueryInterface in rtl\inc\objpash.inc is
> defined as:
> 
> 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;
> IInterface = IUnknown;
> 
> Which after the resolved ifdefs it is compiled in Windows as:
> 
> IUnknown = interface
>   ['{00000000-0000-0000-C000-000000000046}']
>   function QueryInterface(constref iid : tguid;out obj) : longint; stdcall;
>   function _AddRef : longint; stdcall;
>   function _Release : longint; stdcall;
> end;
> IInterface = IUnknown;
> 
> Which breaks the compilation of source code like Zeos which expect the
> "iid: tguid" to be const, not constref.

Iirc, in ZEOS svn this is already solved.

> I'm aware about the changes done to be XPCOM compatible, but at the
> price of "breaking" all existing COM code ? OK, the break is quite
> easy to solve, just replace const by contref, but the question is...
> Is needed to change it to constref in Windows platform too ?
> 
> I know Joost do the changes, but I think direct email is not a good
> choice unless no answer in list of course.

Well, this issue leaded to a large discussion elsewhere. I was wondering
when someone else would even notice this incompatibility. A lot of
alternatives have been discussed, but I coud not find any which is less
intrusive.

In an nutshell: the behavior of 'const' parameters is undefined. When
using cdecl the 'const' keyword is simply ignored. But we do need to
pass the GUID by reference.

There are two options:

1: Change the behavior of const-parameters. That can lead to
unpredictable problems which are not noticed by the compiler. It could
be an option to use some setting to define the behavior of 'const', but
in that case that setting have to be set for all units that do a call to
QueryInterface. (ie: all code using interfaces, so it means this setting
has to be set everywhere where COM code is used)

2: Change the definition to constref, so the compiler will complain if a
user override the QueryInterface's definition, and can adapt the code.

Notice that until now I've only heard of code which overrides
QueryInterface in the Free Pascal code itself, in the Lazarus code, ZEOS
and the code from one commercial developer who also works on
Lazarus/Free Pascal.

It is an incompatibility, yes. But I think it's not too intrusive and I
see no alternatives...

See also:
http://wiki.freepascal.org/User_Changes_Trunk#IInterface.QueryInterface.2C_._AddRef_and_._Release_definitions_have_been_changed

Joost.




More information about the fpc-devel mailing list