Sign in Join

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

Mailing lists / fpc-pascal / 2012-09

Error: Can't take the address of constant expressions

7 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

patspiper

Hi,

Despite
http://wiki.freepascal.org/User_Changes_2.4.0#Treating_direct-mapped_properties_as_regular_fields, shouldn't the following be legal? I tested under FPC 2.6.1 and 2.7.1.

   TMyRecord = record
     Data: pointer;
   end;
   TMyClass = class
   private
     FRef: TMyRecord;
   public
     property Ref: TMyRecord read FRef write FRef;
   end;
var
   MyClass1, MyClass2: TMyClass;
procedure test;
begin
   Move(MyClass1.Ref.Data^, MyClass2.Ref.Data^, 1);
end;

The complete program is attached.

Thanks,
Stephano

Bernd
to patspiper

2012/9/25 patspiper :

Show quoted text 5 lines
Hi, Despite http://wiki.freepascal.org/User_Changes_2.4.0#Treating_direct-mapped_properties_as_regular_fields, shouldn't the following be legal? I tested under FPC 2.6.1 and 2.7.1.

This shouldn't even matter here since IMHO it should work even if Ref were a function (and it works if Ref is a function), it should always work as long as the expression before the ^ is a pointer type.

And interestingly this works also (as it should):

type
  TMyClass = class
  private
    FRef: Pointer;
  public
    property Ref: Pointer read FRef write FRef;
  end;
var
  MyClass1, MyClass2: TMyClass;
procedure test;
begin
  Move(MyClass1.Ref^, MyClass2.Ref^, 1);
end;

but

Move(MyClass1.Ref, MyClass2.Ref, SizeOf(TMyClass.Ref));

will give an error (as it should), no matter how its internally represented because the code that is using this property should not be expected to make assumptions about internal compiler optimizations, it should always treat it like a property.

But your example should work, IMHO you have found a bug.

patspiper
to Bernd
Bernd wrote 14 lines
2012/9/25 patspiper : > procedure test; > begin > Move(MyClass1.Ref.Data^, MyClass2.Ref.Data^, 1); > end; and if you cast it to some other pointer type before dereferencing the error goes away: procedure test; begin Move(MyClass1.Ref.Data^, PByte(MyClass2.Ref.Data)^, 1); end; But this should not be necessary.

Thanks for the feedback. Submitted as:
http://bugs.freepascal.org/view.php?id=22979

Stephano

Vincent Snijders
to Bernd: 2012/9/25 patspiper : and if you cast it to some other pointer type before dereferencing…

2012/9/25 Bernd :

Show quoted text 15 lines
2012/9/25 patspiper : > procedure test; > begin > Move(MyClass1.Ref.Data^, MyClass2.Ref.Data^, 1); > end; and if you cast it to some other pointer type before dereferencing the error goes away: procedure test; begin Move(MyClass1.Ref.Data^, PByte(MyClass2.Ref.Data)^, 1); end; But this should not be necessary.

Why not? The error is correct. By using the type cast you tell the compiler you know what you are doing and that is should not bother doing the sanity check.

So IMO, not a bug.

Vincent

patspiper
to Vincent Snijders
Vincent Snijders wrote 20 lines
2012/9/25 Bernd: > 2012/9/25 patspiper: >> procedure test; >> begin >> Move(MyClass1.Ref.Data^, MyClass2.Ref.Data^, 1); >> end; > and if you cast it to some other pointer type before dereferencing the > error goes away: > > procedure test; > begin > Move(MyClass1.Ref.Data^, PByte(MyClass2.Ref.Data)^, 1); > end; > > But this should not be necessary. Why not? The error is correct. By using the type cast you tell the compiler you know what you are doing and that is should not bother doing the sanity check. So IMO, not a bug.

Can anybody test under Delphi? The complete unit is in the OP.

Stephano

Jonas Maebe
to Vincent Snijders: 2012/9/25 Bernd : Why not? The error is correct. By using the type cast you tell the…
Vincent Snijders wrote 20 lines
2012/9/25 Bernd : > 2012/9/25 patspiper : >> procedure test; >> begin >> Move(MyClass1.Ref.Data^, MyClass2.Ref.Data^, 1); >> end; > > and if you cast it to some other pointer type before dereferencing the > error goes away: > > procedure test; > begin > Move(MyClass1.Ref.Data^, PByte(MyClass2.Ref.Data)^, 1); > end; > > But this should not be necessary. Why not? The error is correct. By using the type cast you tell the compiler you know what you are doing and that is should not bother doing the sanity check.

If that were true, then using a local variable that is an untyped pointer would also have to fail. It is in fact a compiler bug.

Jonas