Recent

Author Topic: Anonymous Unions-Middle Road variants in records.  (Read 1884 times)

jamie

  • Hero Member
  • *****
  • Posts: 6735
Anonymous Unions-Middle Road variants in records.
« on: May 29, 2023, 07:07:30 pm »
has there been any thought yet, for supporting anonymous records inside records so we can wrap it around a Variant in the middle of the base record?


  It's very difficult to translate anonymous C unions that reside before the end of the record/struct without adding a new name tag. Adding name tags makes a mess out of translating a large C/C++ code base, especially the types I deal with.

 Either FPC can have a UNION that behaves like a C UNIT or make a nameless record with a following CASE ... OF .. END that only is allowed within a starting record define.


 
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 16201
  • Censorship about opinions does not belong here.
Re: Anonymous Unions-Middle Road variants in records.
« Reply #1 on: May 30, 2023, 04:36:52 am »
That's more or less why I introduced OpaqueRecord and POpaqueRecord (system unit).
This should cover your C translations.
If I smell bad code it usually is bad code and that includes my own code.

Fibonacci

  • Hero Member
  • *****
  • Posts: 614
  • Internal Error Hunter
Re: Anonymous Unions-Middle Road variants in records.
« Reply #2 on: May 30, 2023, 09:18:35 am »
Seconded! Nameless records and case-of records not only at the end of the record.

And less RTTI!

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Anonymous Unions-Middle Road variants in records.
« Reply #3 on: May 30, 2023, 02:07:59 pm »
Hope and change!  :)
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Anonymous Unions-Middle Road variants in records.
« Reply #4 on: May 31, 2023, 02:24:53 am »
I wanted to add that there is a way of doing this but it's very messy.

Code: Pascal  [Select][+][-]
  1. type
  2.   TUnion = Record
  3.     Case boolean of
  4.      True :(A:integer;
  5.       C:Integer); //Remainder of record here.
  6.      false:(B:integer);
  7.  End;                              
  8.  

If you look at this construct, A and B field live in the same space.
if you expand, lets say A to include more data, this extra data will actually be there following those A,B unions but C will live after those either way.
 
 This means that you need to build the remainder of the record like this, and that can even include another nested variant for which you extend any following more non-UNION fields in the same way

keep this up and it will look like a Tree.

 This mess only needs to be used if you have anonymous unions/variants, otherwise, you can wrap the variant with a named record type within or outside type.

The only true wisdom is knowing you know nothing

Warfley

  • Hero Member
  • *****
  • Posts: 1767
Re: Anonymous Unions-Middle Road variants in records.
« Reply #5 on: May 31, 2023, 01:15:00 pm »
What's wrong with this:
Code: Pascal  [Select][+][-]
  1.       TTest = record
  2.         A: Integer;
  3.         B: record
  4.           case Boolean of
  5.           True: (A: Integer);
  6.           False: (B: Integer);
  7.         end;
  8.         C: Integer;
  9.       end;

It already works, but I don't know if this is C compatible (in terms of alignment)

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Anonymous Unions-Middle Road variants in records.
« Reply #6 on: May 31, 2023, 01:53:45 pm »
What's wrong with this:
Code: Pascal  [Select][+][-]
  1.       TTest = record
  2.         A: Integer;
  3.         B: record
  4.           case Boolean of
  5.           True: (A: Integer);
  6.           False: (B: Integer);
  7.         end;
  8.         C: Integer;
  9.       end;

It already works, but I don't know if this is C compatible (in terms of alignment)
No, that isn't the same and doesn't work in the way of the nameless union.

 In your example:
    "A" at the first entry will always be there by itself and no other item will live there.

In my example:
    "A" and "B" share the same memory location at the start.

 Your use of a record solves many problems except for the fact that it does not solve the anonymous issues, you have now forced a new tag requirement.

  You will also note that I extended the first branch of "A" to add additional items in the record. These items are now not in the realm being selective, they are basically following after either "A" or "B".

 Maybe I should of make the example different.
Code: Pascal  [Select][+][-]
  1. Type
  2.  TAnonymousExample = Record
  3.    Case boolean of
  4.     True :(A:Integer);
  5.     False:(B:Integer;
  6.        C:Integer;
  7.        S:String[10];
  8.        W:WORD;)
  9. End;
  10.  

 Looking at that code, C,S and W will always exist following A or B. where A and B occupy the same space.
 
 You will also note, there is no additional TAGS being added.

 This of course makes for a messy looking record but it does work just like C anonymous unions. The downside is that you need to complete the record in the tree order of the CASE...
The only true wisdom is knowing you know nothing

Warfley

  • Hero Member
  • *****
  • Posts: 1767
Re: Anonymous Unions-Middle Road variants in records.
« Reply #7 on: May 31, 2023, 02:13:19 pm »
Ah ok I understand you mean anonymous record fields not an anonymous record type (i.e. a non named type).

That's not possible, but you can just use properties to use them transparently:

Code: Pascal  [Select][+][-]
  1. program test;
  2.  
  3. {$Mode ObjFPC}
  4. {$ModeSwitch AdvancedRecords}
  5.  
  6. type
  7.   TTest = record
  8.     A: Integer;
  9.     _Union_: record
  10.     case Boolean of
  11.     True: (s: Char);
  12.     False: (b: Byte);
  13.    end;
  14.    C: Integer;
  15.    
  16.    property S: Char read _Union_.s write _Union_.s;
  17.    property B: Byte read _Union_.b write _Union_.b;
  18.  end;
  19.  
  20. var
  21.   T: TTest;
  22. begin
  23.         t.s := 'A';
  24.         WriteLn(chr(t.B));
  25. end.

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Anonymous Unions-Middle Road variants in records.
« Reply #8 on: May 31, 2023, 02:25:54 pm »
yes, I know about the properties. I have done that using a static OBJECT which behaves just like a advanced record.

For the interim, I think for more simpler records, I'll stick with the PASCAL way since it is part of the language, just a butchered way of doing anonymous fields until real UNIONS or at least a hybrid to the variant exists.
 8)
The only true wisdom is knowing you know nothing

Warfley

  • Hero Member
  • *****
  • Posts: 1767
Re: Anonymous Unions-Middle Road variants in records.
« Reply #9 on: May 31, 2023, 02:31:22 pm »
I must say with objects im never sure about the memory layout. With classes you can't make assumptions (there will be the hidden VMT, rtti and what not, and I think -O4 will reorder class fields), with records you exactly get what you write down. Objects are somewhat between those two (I think there is a VMT) but I am never sure on how reliable this is.

So I personally really like records because they are simple, and with advanced records I get some syntactic sugar (like the properties), but nothing to complex like virtual methods or inheritance

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Anonymous Unions-Middle Road variants in records.
« Reply #10 on: May 31, 2023, 06:08:15 pm »
There is no VMT if you don't use constructors in it.
and the layout is the same as the records. I have used objects like this before Advanced records came along to get the features of properties, hidden areas etc.

  Oh well, I don't see objects going away anytime soon.  :D
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018