Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2010-10

FPC_HAS_CONSTREF

11 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Marcos Douglas

Hi,
I updated my FPC (2.5.1) and Lazarus (0.9.29 rev 27706) and, now, I can't compile the Zeos package (ver 6.6.6).

The error is:
[...]\zeos\6.6.6-stable\src\core\ZClasses.pas(84,22) Error: No matching implementation for interface method "IUnknown.QueryInterface(constref TGuid,out <Formal type>):LongInt; StdCall;" found

There is, in objpash.inc, line 246:
function QueryInterface({$IFDEF
FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) :
longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};

What is "constref", where was defined FPC_HAS_CONSTREF and how use this?

Thanks,

Marcos Douglas

Reply by email

Jonas Maebe
to Marcos Douglas
Marcos Douglas wrote 6 lines
There is, in objpash.inc, line 246: function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; What is "constref",

A "const" parameter that is always passed by reference.

where was defined FPC_HAS_CONSTREF and how use this?

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

Jonas

Reply by email

Marcos Douglas
to Jonas Maebe
Jonas Maebe wrote 15 lines
On 21 Oct 2010, at 21:05, Marcos Douglas wrote: > There is, in objpash.inc, line 246: > function QueryInterface({$IFDEF > FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : > longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; > > What is "constref", A "const" parameter that is always passed by reference. > where was defined FPC_HAS_CONSTREF and how use this? http://wiki.freepascal.org/User_Changes_Trunk#IInterface.QueryInterface.2C_._AddRef_and_._Release_definitions_have_been_changed

Thanks Jonas.
I'll change the Zeos source...

Marcos Douglas

Reply by email

Hans-Peter Diettrich
to Jonas Maebe: A "const" parameter that is always passed by reference.…
> What is "constref", A "const" parameter that is always passed by reference.

What's the guarantee, that (in detail external) subroutines will honor the "const" attribute?

AFAIK "constref" was invented for passing values to external subroutines, that expect a reference. In how far does "constref" affect the *caller*, in contrast to e.g. "var"? Can constref pass properties, which are not allowed as var parameters?

DoDi

Reply by email

Jonas Maebe
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 7 lines
Jonas Maebe schrieb: >> What is "constref", > A "const" parameter that is always passed by reference. What's the guarantee, that (in detail external) subroutines will honor the "const" attribute?

None. "const" (and constref) is a hint from the programmer that the argument can be considered by the compiler as "constant" inside the called routine. If the called routine is compiled by FPC, FPC itself will perform a number of checks that catch the most obvious ways to modify const arguments, but there are plenty of ways to work around that (e.g., pointers, assembler code, passing a global variable via constref and then modifying the global variable directly in the called routine, ...).

AFAIK "constref" was invented for passing values to external subroutines, that expect a reference. In how far does "constref" affect the *caller*, in contrast to e.g. "var"? Can constref pass properties, which are not allowed as var parameters?

Right now it's allowed (if the property uses a getter, the getter is called and its result is put into a temp location whose address is passed), but I think that's a bug in the implementation.

Jonas

Reply by email

Martin
to Jonas Maebe
Jonas Maebe wrote 10 lines
> AFAIK "constref" was invented for passing values to external > subroutines, that expect a reference. In how far does "constref" > affect the *caller*, in contrast to e.g. "var"? Can constref pass > properties, which are not allowed as var parameters? Right now it's allowed (if the property uses a getter, the getter is called and its result is put into a temp location whose address is passed), but I think that's a bug in the implementation.

Why?

If constref *guarantees* a ref, then that sounds correct (Using a temp var).

IMHO the importance would be to make sure, that a property without a getter function, does also use a tempvar => so the behaviour does not change, if the property changes to use a getter.

Then again it could be argued, if the developer used constref, he promised not to touch the value, if he breaks that promise, and get's burned... (where is that mail about shoting yourself in the foot...)

Martin

Reply by email

Jonas Maebe
to Martin
Martin wrote 8 lines
On 22/10/2010 12:28, Jonas Maebe wrote: > >> AFAIK "constref" was invented for passing values to external subroutines, that expect a reference. In how far does "constref" affect the *caller*, in contrast to e.g. "var"? Can constref pass properties, which are not allowed as var parameters? > > > Right now it's allowed (if the property uses a getter, the getter is called and its result is put into a temp location whose address is passed), but I think that's a bug in the implementation. Why?

Because it's not possible to pass a reference to a property.

Jonas

Reply by email

Martin
to Jonas Maebe
Jonas Maebe wrote 8 lines
On 22 Oct 2010, at 15:09, Martin wrote: > On 22/10/2010 12:28, Jonas Maebe wrote: >>> AFAIK "constref" was invented for passing values to external subroutines, that expect a reference. In how far does "constref" affect the *caller*, in contrast to e.g. "var"? Can constref pass properties, which are not allowed as var parameters? >> >> Right now it's allowed (if the property uses a getter, the getter is called and its result is put into a temp location whose address is passed), but I think that's a bug in the implementation. > Why? Because it's not possible to pass a reference to a property.

True, but that only matters if you intend to change the value of the property, by changing the value that the reference points to. const and constref do not make the promise that the refereed value can be used to change the original value

If I understand correctly:

const: is merely a hint, without any further promise. It allows fpc to assume the receiver is not going to attempt to change the value. (used for ansistring, by omitting increasing the ref count). So, even const could pass a reference to a temporary copy, without breaking any documented behaviour.

constref: is the same hint, combined with the promise of a reference. That is the expectation is that the receiver can read the value via a pointer.
That is also that fpc can act as if the receiver was not going to change the value, therefore if the reference points to a temporary copy of the value, the documented behaviour is still fulfilled?

Martin

Reply by email

Martin
to Martin
Martin wrote 18 lines
On 22/10/2010 15:24, Jonas Maebe wrote: > On 22 Oct 2010, at 15:09, Martin wrote: > >> On 22/10/2010 12:28, Jonas Maebe wrote: >>>> AFAIK "constref" was invented for passing values to external >>>> subroutines, that expect a reference. In how far does "constref" >>>> affect the *caller*, in contrast to e.g. "var"? Can constref pass >>>> properties, which are not allowed as var parameters? >>> >>> Right now it's allowed (if the property uses a getter, the getter >>> is called and its result is put into a temp location whose address >>> is passed), but I think that's a bug in the implementation. >> Why? > Because it's not possible to pass a reference to a property. True, but that only matters if you intend to change the value of the property, by changing the value that the reference points to. const and constref do not make the promise that the refereed value can be used to change the original value

In other words, as I understand (correct me if needed):

you are not passing the property ever:
   property FooP: TSomeType;
   var FooV: TSomeType;
procedure Bar(SomeFoo TSomeType);
Bar(FooP);
- you are passing the value of the property
Bar(FooV);
- you are passing the value of the variable, not the variable itself

procedure Bar(const SomeFoo TSomeType);
procedure Bar(constref SomeFoo TSomeType);
Bar(FooP);
- you are passing a reference to the value of the property (not a reference to the property)
Bar(FooV);
- you are passing a reference to the value of the variable it just happens to be a reference to the same memory that is used by the variable itself. This is because it's an optimization, the compiler made due to the hint it was given

procedure Bar(var SomeFoo TSomeType);
- In this case a reference to the variable is needed, so it can be modified.

Reply by email

Jonas Maebe
to Hans-Peter Diettrich: What about reference counting or similar stuff, that differs for const and other…
Hans-Peter Diettrich wrote 6 lines
Jonas Maebe schrieb: >> What's the guarantee, that (in detail external) subroutines will honor the "const" attribute? > None. "const" (and constref) is a hint from the programmer that the argument can be considered by the compiler as "constant" inside the called routine. What about reference counting or similar stuff, that differs for const and other arguments?

It's the same for const and constref.

>> In how far does "constref" affect the *caller*, in contrast to e.g. "var"? Can constref pass properties, which are not allowed as var parameters? > Right now it's allowed (if the property uses a getter, the getter is called and its result is put into a temp location whose address is passed), but I think that's a bug in the implementation. When this feature is removed, does there remain any difference between var and constref, at the calling side?

At least you cannot pass a const parameter to a var parameter, while you can pass a const parameter to a constref parameter. Since it's always possible to take the address of a const parameter (unlike of a property), this is semantically consistent.

Jonas

Reply by email

Hans-Peter Diettrich
to Jonas Maebe: None. "const" (and constref) is a hint from the programmer that the argument can be…
Show quoted text 6 lines
> What's the guarantee, that (in detail external) subroutines will honor > the "const" attribute? None. "const" (and constref) is a hint from the programmer that the argument can be considered by the compiler as "constant" inside the called routine.

What about reference counting or similar stuff, that differs for const and other arguments?

Show quoted text 8 lines
> In how far does "constref" > affect the *caller*, in contrast to e.g. "var"? Can constref pass > properties, which are not allowed as var parameters? Right now it's allowed (if the property uses a getter, the getter is called and its result is put into a temp location whose address is passed), but I think that's a bug in the implementation.

When this feature is removed, does there remain any difference between var and constref, at the calling side?

DoDi

Reply by email