Error: Can't take the address of constant expressions

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Error: Can't take the address of constant expressions

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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

constaddresstest.lpr (527 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Error: Can't take the address of constant expressions

Bernd K.
2012/9/25 patspiper <[hidden email]>:
> 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.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Error: Can't take the address of constant expressions

Bernd K.
In reply to this post by patspiper
2012/9/25 patspiper <[hidden email]>:
> 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.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Error: Can't take the address of constant expressions

patspiper
On 25/09/12 20:43, Bernd wrote:

> 2012/9/25 patspiper <[hidden email]>:
>> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Error: Can't take the address of constant expressions

Vincent Snijders-3
In reply to this post by Bernd K.
2012/9/25 Bernd <[hidden email]>:

> 2012/9/25 patspiper <[hidden email]>:
>> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Error: Can't take the address of constant expressions

patspiper
On 26/09/12 08:58, Vincent Snijders wrote:

> 2012/9/25 Bernd<[hidden email]>:
>> 2012/9/25 patspiper<[hidden email]>:
>>> 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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Error: Can't take the address of constant expressions

Jonas Maebe-2
In reply to this post by Vincent Snijders-3

On 26 Sep 2012, at 07:58, Vincent Snijders wrote:

> 2012/9/25 Bernd <[hidden email]>:
>> 2012/9/25 patspiper <[hidden email]>:
>>> 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_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal