Recent

Author Topic: [SOLVED] Classic objects — does FPC generate additional code?  (Read 2724 times)

flowCRANE

  • Hero Member
  • *****
  • Posts: 901
[SOLVED] Classic objects — does FPC generate additional code?
« on: December 13, 2024, 03:09:56 pm »
From what I understand, classic objects, i.e. data structures declared with the object keyword, take up the same amount of memory as their record counterparts. We can declare such objects on the stack and on the heap, but unlike records, objects support inheritance. So they are something between records and classes, which gives additional possibilities, which I am happy to use.

In my game engine, I use such classic objects to create simple data structures that contain only fields with data (no methods) and this data can be inherited. Such objects can be used as local variables existing on the stack, but can also be allocated on the heap. When allocated on the heap, memory for them is always allocated using GetMem and freed using FreeMem. That's it in a nutshell.

Assuming that:

  • objects contain only fields, no methods, constructors, destructors or properties,
  • I use GetMem and FreeMem to manage their memory on the heap,
  • if I use an object that exists on the stack, I never use New and Dispose functions.

can someone familiar with FPC internals officially confirm that using objects only with fields and not using the API dedicated to classic objects (constructors, destructors, New, Dispose etc.) makes such objects exactly the same as regular records? So far, I have not found that using them in the manner mentioned above would result in the automatic allocation of additional memory or forces the compiler to generate additional instructions.

Thanks in advance for your answers.
« Last Edit: December 14, 2024, 01:30:29 am by flowCRANE »
Lazarus 3.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11984
  • FPC developer.
Re: Classic objects — does FPC generate additional code?
« Reply #1 on: December 13, 2024, 03:18:05 pm »
What OO do you have left then?  Records can contain methods. TP objects only allocate a VMT when virtual methods are defined.

I'm not sure using getmen and freemem handle fields with automated types. You would have to add initialize and finalize calls for that.

I would simply use records and use new and dispose.

flowCRANE

  • Hero Member
  • *****
  • Posts: 901
Re: Classic objects — does FPC generate additional code?
« Reply #2 on: December 13, 2024, 03:54:02 pm »
What OO do you have left then?  Records can contain methods.

As I wrote, I don't need methods and properties — simple fields only.
I use objects instead of records because objects support inheritance and records do not.

Quote
TP objects only allocate a VMT when virtual methods are defined.

Ok, I'm glad to hear this.

Quote
I'm not sure using getmen and freemem handle fields with automated types. You would have to add initialize and finalize calls for that.

This is not a problem, because I always declare an initialization and finalization function, as well as an allocating and deallocating function for each record and object. This way I can freely use such data structures and allocate them on both the stack and the heap, regardless of whether they contain fields that require initialization/finalization.

Thank you for the answer!
Lazarus 3.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

Warfley

  • Hero Member
  • *****
  • Posts: 1849
Re: Classic objects — does FPC generate additional code?
« Reply #3 on: December 13, 2024, 03:56:32 pm »
I don't think so. In the internal representation in the FPC objects are closer to classes than to records (classes are just represented as objects with a special flag while records have their own internal representation). While it's true that objects do not get a vmt if they don't need one, I don't think they give the same guarantees as records with internal layout. I think like classes, object fields can be reordered by the optimizer.
So generally speaking I would not bet on it

flowCRANE

  • Hero Member
  • *****
  • Posts: 901
Re: Classic objects — does FPC generate additional code?
« Reply #4 on: December 13, 2024, 04:05:15 pm »
Guys, I need facts, not beliefs or opinions.

I found no evidence that FPC generates additional code or allocates additional memory for TP objects containing only simple fields. But I'd rather ask and make it clear once and for all. And I'd prefer someone who knows exactly how the compiler handles TP objects to answer. Even on this forum I have found beliefs that TP objects are not compatible with records, although no concrete evidence has been provided to support these theses.

Here I'm asking about a specific case — an TP object with simple fields only (no methods, especially virtual ones).
Lazarus 3.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11984
  • FPC developer.
Re: Classic objects — does FPC generate additional code?
« Reply #5 on: December 13, 2024, 04:32:16 pm »
What OO do you have left then?  Records can contain methods.

As I wrote, I don't need methods and properties — simple fields only.
I use objects instead of records because objects support inheritance and records do not.

Non virtual inheritance is possible I guess, that wouldn't require a VMT.  But any kind of polymorphism will be hard.

flowCRANE

  • Hero Member
  • *****
  • Posts: 901
Re: Classic objects — does FPC generate additional code?
« Reply #6 on: December 13, 2024, 04:39:40 pm »
But any kind of polymorphism will be hard.

It's not a problem, neither for records nor for TP objects. That's because whenever I need to pass a structure reference or TP object, I do it via a weak (untyped) pointer, thanks to {$TYPEDADDRESS OFF} mode. This gives me full polymorphism (for any data) and eliminates the need for the notorious casting.
Lazarus 3.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

Thaddy

  • Hero Member
  • *****
  • Posts: 16343
  • Censorship about opinions does not belong here.
Re: Classic objects — does FPC generate additional code?
« Reply #7 on: December 13, 2024, 05:15:51 pm »
NO

simple and short answer.
There is nothing wrong with being blunt. At a minimum it is also honest.

flowCRANE

  • Hero Member
  • *****
  • Posts: 901
Re: Classic objects — does FPC generate additional code?
« Reply #8 on: December 13, 2024, 08:12:59 pm »
As I wrote — I need facts, not simple and short answers. Beliefs don't work well with technology.
Lazarus 3.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

Warfley

  • Hero Member
  • *****
  • Posts: 1849
Re: Classic objects — does FPC generate additional code?
« Reply #9 on: December 13, 2024, 10:46:49 pm »
The problem is that you are asking something that is undocumented. The documentation for records clearly state their memory layout and management, records are designed to be ABI stable, objects not.
Maybe what you want works, maybe it doesn't, maybe it works now but not anymore in the next version of the FPC. FPC has a few hundred thousand lines of code, a quick search for the corresponding type tobjectdef shows over 1000 occurrences in the code. So making a definite claim is not really easy

At least from the documentation I can tell you that ABI stability is not a design criterium of objects and as such even if it may be the case now there is no guarantee it will stay this way

flowCRANE

  • Hero Member
  • *****
  • Posts: 901
Re: Classic objects — does FPC generate additional code?
« Reply #10 on: December 13, 2024, 11:18:26 pm »
The problem is that you are asking something that is undocumented. […] FPC has a few hundred thousand lines of code, a quick search for the corresponding type tobjectdef shows over 1000 occurrences in the code. So making a definite claim is not really easy.

And that's why I'm asking you guys, hoping to find out something that is not in the documentation. 8)

Quote
At least from the documentation I can tell you that ABI stability is not a design criterium of objects and as such even if it may be the case now there is no guarantee it will stay this way

Now that's a clue.

It's a pity that standard records don't support protected content. Of course, the point is not to have their own VMT, but to make the content of records visible only in the module of their declaration and in modules with declarations of records inheriting from them. If that were the case, I would use regular records to achieve sensible encapsulation of simple data structures, and not bother with TP objects.

But as we know, records not only do not support protected content, but also the inheritance itself.
« Last Edit: December 13, 2024, 11:21:29 pm by flowCRANE »
Lazarus 3.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

TRon

  • Hero Member
  • *****
  • Posts: 3776
Re: Classic objects — does FPC generate additional code?
« Reply #11 on: December 13, 2024, 11:21:12 pm »
It's a pity that standard records don't support protected content. Of course, the point is not to have their own VMT, but to make the content of records visible only in the module of their declaration and in modules with declarations of records inheriting from them. If that were the case, I would use regular records to achieve sensible encapsulation of simple data structures, and not bother with TP objects.
huh ? afaik that mechanism is in place with advanced records, e.g. private/public parts. Or is that not what you meant ?
I do not have to remember anything anymore thanks to total-recall.

flowCRANE

  • Hero Member
  • *****
  • Posts: 901
Re: Classic objects — does FPC generate additional code?
« Reply #12 on: December 13, 2024, 11:22:26 pm »
TRon: you are right but, advanced records does not support protected sections and does not supports inheritance.

These are the two things I would like to have available for regular records. Currently, I hide the record fields by declaring them in private sections (one section for all the record content), and I achieve inheritance, protected content, and binary compatibility with records by using TP objects.
« Last Edit: December 13, 2024, 11:25:24 pm by flowCRANE »
Lazarus 3.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

TRon

  • Hero Member
  • *****
  • Posts: 3776
Re: Classic objects — does FPC generate additional code?
« Reply #13 on: December 13, 2024, 11:28:53 pm »
Ah ok, yes. Got it now (I should have read the thread with more attention, sorry about that)

To get back to your original question: Isn't that visible with looking at the generated assembler code ?

I do not have to remember anything anymore thanks to total-recall.

flowCRANE

  • Hero Member
  • *****
  • Posts: 901
Re: Classic objects — does FPC generate additional code?
« Reply #14 on: December 13, 2024, 11:35:02 pm »
I've checked the assembly for various examples and found nothing suspicious. In addition, SizeOf always returns the correct size of a TP object, which is always the sum of its fields (plus alignment). So, so far, I haven't found any evidence that a TP object containing only fields is not binary compatible with records.
Lazarus 3.6 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on a retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

 

TinyPortal © 2005-2018