Recent

Author Topic: Accessing Property via Pointer  (Read 1081 times)

kupferstecher

  • Hero Member
  • *****
  • Posts: 603
Accessing Property via Pointer
« on: February 20, 2024, 01:36:43 pm »
Hello all,

see below code, I try to set the value of a property through a pointer. The property is mapped to a function, so I wished the compiler would call the setter, by dereferencing the pointer pointing to the property. I guessed that it isn't even possible so I made a little test (below code). And I didn't get it to work, the function isn't called. But also no warning/error is given by the compiler. Is this by design?

So what actually happens in line 27?

Thanks!

(FPC3.2.2, 64 bit)
Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. Type TFoo= class
  4.   fSth:Integer;
  5.   procedure setSth(AValue:Integer);
  6.   Property sth: Integer read fSth write setSth;
  7. end;
  8.  
  9. procedure TFoo.setSth(AValue:Integer);
  10. begin
  11.   fSth:= AValue;
  12.   writeln('fSth:',fSth);
  13. end;
  14.  
  15. var
  16.   Foo: TFoo;
  17.   pSth: ^Integer;
  18.  
  19. begin
  20.  
  21.   Foo:= TFoo.create;
  22.   Foo.sth:= 3;           //-> output 'fSth:3'
  23.  
  24.   pSth:= @Foo.sth;
  25.   pSth^:= 7;             //-> No output, expected 'fSth: 7'
  26.  
  27.   readln;
  28. end.  


Fibonacci

  • Hero Member
  • *****
  • Posts: 594
  • Internal Error Hunter
Re: Accessing Property via Pointer
« Reply #1 on: February 20, 2024, 01:41:28 pm »
It just doesnt work like that. You directly accessed the memory and changed the value to 7, dont expect for the setter to be called.

Thaddy

  • Hero Member
  • *****
  • Posts: 16144
  • Censorship about opinions does not belong here.
Re: Accessing Property via Pointer
« Reply #2 on: February 20, 2024, 04:38:09 pm »
It is only possible through assembler.
If I smell bad code it usually is bad code and that includes my own code.

kupferstecher

  • Hero Member
  • *****
  • Posts: 603
Re: Accessing Property via Pointer
« Reply #3 on: February 20, 2024, 06:33:52 pm »
You directly accessed the memory and changed the value to 7, dont expect for the setter to be called.
But which memory... After a further test it seems when setting the pointer with @Foo.Sth the "read" part of the property is taken, and when I change the property's read to a method, then there is an error. It's understandable for me now, but a pity, that it won't work.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10542
  • Debugger - SynEdit - and more
    • wiki
Re: Accessing Property via Pointer
« Reply #4 on: February 20, 2024, 07:46:29 pm »
Afaik, you shouldn't even be able to take the address of a property
Code: Pascal  [Select][+][-]
  1.  pSth:= @Foo.sth;
That should generate an error.

In the same way as
Code: Pascal  [Select][+][-]
  1.  inc(Foo.sth);
gives an error.


There is an existing report https://gitlab.com/freepascal.org/fpc/source/-/issues/30017

From other similar prior cases I personally would expect that the fix will be to make both properties give an error when their address is taken.
« Last Edit: February 20, 2024, 07:51:50 pm by Martin_fr »

Thaddy

  • Hero Member
  • *****
  • Posts: 16144
  • Censorship about opinions does not belong here.
Re: Accessing Property via Pointer
« Reply #5 on: February 20, 2024, 07:59:59 pm »
No, just do not misuse properties, use fields. A getter would need a call. So asm is required. You can't bluntly substitute an address with a call.
If I smell bad code it usually is bad code and that includes my own code.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8007
Re: Accessing Property via Pointer
« Reply #6 on: February 20, 2024, 08:19:00 pm »
I am by no means a fluent interpreter of the entrails of the FPC compiler, but would point you at this recent thread https://forum.lazarus.freepascal.org/index.php/topic,66220.msg506413.html#msg506413 where Remy (and others) was surprised by the fact that a setter was able to accept a var parameter rather than one passed purely by value.

The implication of this is that instead of a property corresponding to predefined procedure and function types as the setter and getter, they behave almost like macros with replacement done at the source level which is later resolved to any suitable entry point.

So like others, I'm surprised that your code is accepted by the compiler, and there's a real risk that if you do that you'll generate something pathological: the answer to your question has to be "Dunno, take a look at the generated assembler" :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

kupferstecher

  • Hero Member
  • *****
  • Posts: 603
Re: Accessing Property via Pointer
« Reply #7 on: February 20, 2024, 09:48:28 pm »
Afaik, you shouldn't even be able to take the address of a property
Code: Pascal  [Select][+][-]
  1.  pSth:= @Foo.sth;
That should generate an error.

Yes, I think so. When I testet it I didn't really expect it to work (though would be good). If there were such an error I wouldn't have asked here.

Quote
In the same way as
Code: Pascal  [Select][+][-]
  1.  inc(Foo.sth);
gives an error.

Ah, I remember such a discussion here on the forum. And somehow can understand the reasoning (double access because of read plus write, while one could assume a single operation?). But I think it would come handy and make properties much more useful. For the outside of the class it would behave just like a regular variable. Because of the restriction I cannot pass the property to a function, so I either have to explicitely call the property (i.e. hard code it), or pass setters and getters, which is more effort to implement. Instead the compiler should just do its magic~

A getter would need a call. So asm is required. You can't bluntly substitute an address with a call.
I see your point, the compiler (or the generated code) can't really know that the pointer address in the moment of dereferencing is pointing on a property instead of a plain variable. Perhaps a special property pointer would be needed. But yes, ...

Code: Pascal  [Select][+][-]
  1. pSth: ^Property of Integer;

(just a joke)


The implication of this is
a bit difficult to grasp :)

 

TinyPortal © 2005-2018