Recent

Author Topic: Can this C struct be expressed in FPC Pascal ?  (Read 4710 times)

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2282
    • havefunsoft.com
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #75 on: July 08, 2019, 04:26:04 am »
Someone please document it on the wiki page. It can be valuable for new users coming from C.
https://wiki.freepascal.org/Flexible_Array_Member
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

Handoko

  • Hero Member
  • *****
  • Posts: 3188
  • My goal: build my own game engine using Lazarus
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #76 on: July 08, 2019, 05:07:42 am »
 :) Good, we make it one less reason C users can't port their codes to Pascal.

440bx

  • Hero Member
  • *****
  • Posts: 1198
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #77 on: July 08, 2019, 06:53:26 am »
https://wiki.freepascal.org/Flexible_Array_Member
Nicely done.

Just a few comments on the contents.

It is correct that flexible array members, i.e, array[], are not part of the C++ standard but, MS C++ supports it and, I believe but I am not sure, g++ does as well.

Both of them support a construct that is mostly equivalent, that is, array[0].

The older api struct definitions used array[1] (or ANYSIZE_ARRAY to make it clearer that it wasn't really just a single byte array.)  MS used array[0] in a _very small_ number of struct definitions.  Currently MS seems to favor array[] (the impression I get is that for new variable length structs, array[] is what they are consistently using.)

More precisely, a quick parse of a fairly small but representative subset of the Windows API produced the following:

a. array[ANYSIZE_ARRAY] : 69 occurrences, all of them in structs that have existed a very long time.

b. array[0] : 2 occurrences, hard to see a timing pattern in such a rather small sample.

c. array[] : 7 occurrences, all seven are fairly recent struct definitions, leading to the impression that is what MS is favoring since among the recent structs neither 0 nor ANYSIZE_ARRAY seems to be used. 

while array[] is somewhat rare right now, it might become more common as the number of new variable length structs increases.

The other comment is, I believe it would be useful to include Marco's implementation of flexible array member in Pascal, that is::
Code: Pascal  [Select]
  1.   FlexRec = record
  2.      a        : DWORD;
  3.      b        : DWORD;
  4.      c        : array[0..0] of record end;   { cannot specify a type          }
  5.   end;
  6.  
and document that this solution will require defining a typed pointer as the address of "c" in order to access the elements in the array. 

Also associated with how the array elements are accessed, I believe it would be good to mention that when a function or property is used to define/access the array "c", it is no longer possible to take the address of an array element (this can make the construction unusable if the original C code uses pointers to access the array elements, a rather common practice in C.)
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 673
  • Compiler Developer
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #78 on: July 08, 2019, 09:19:24 am »
using that style of coding here's my HACK!,,. still.
Code: Pascal  [Select]
  1. TmyRecord = Packed Record
  2.  A,B:DWord;
  3.  Function C(Index:Integer):DWord; inline;
  4.  Procedure C(Index:Integer;AValue:DWord); inline;
  5.  End;
  6. var
  7.   Form1: TForm1;
  8.  
  9. implementation
  10.  
  11. {$R *.lfm}
  12.  
  13. { TForm1 }
  14. Procedure TMyRecord.C(Index:Integer; AValue:DWord);
  15. begin
  16.  PWord(SizeOf(Self)+UintPtr(@Self))[Index] := AValue;
  17. end;
  18.  
  19. Function TMyrecord.C(Index:Integer):DWord;
  20. Begin
  21.   Result := PWord(SizeOf(Self)+UIntPtr(@Self))[index];
  22. End;
  23. procedure TForm1.FormCreate(Sender: TObject);
  24. Var
  25.   T:TmyRecord;
  26.   A:Dword;
  27.   M:Pointer;
  28. begin
  29.   M := GetMem(1000);
  30.   TMyRecord(M^).C(1,100);
  31.   A := TmyRecord(M^).C(1);
  32.   Caption := A.ToString;
  33.   Freemem(M);
  34. end;                                  
  35.  
There is no need for an additional setter. Assuming the record is declared like this (as mentioned in some posts already):
Code: Pascal  [Select]
  1. type
  2.   mystruct = packed record
  3.     a,b: DWORD;
  4.     function c: PDWORD; inline; // return adress after record
  5.   end;
  6.   pmystruct = ^mystruct;
  7.      
  8. function mystruct.c: PDWORD;
  9. begin
  10.   c := PDWORD(@self+1);
  11. end;

Your example usage then becomes this:
Code: Pascal  [Select]
  1. var
  2.   s: pmystruct;
  3.   v: DWord;
  4.   m: Pointer;
  5. begin
  6.   m := GetMem(1000);
  7.   s := pmystruct(m);
  8.   s^.c[1] := 100;
  9.   v := s^.c[1];
  10.   Writeln(v);
  11.   Freemem(v);
  12. end.
This is as close to the usage of the record in C as you can get. The record is after all only declared once, but it's used much more often.

By the way: you have an error in your code: you need to use PDWord in your C methods, not PWord.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 635
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #79 on: July 08, 2019, 11:11:42 am »
All this work to make buggy and unmaintainable code.  %)

Thaddy

  • Hero Member
  • *****
  • Posts: 9181
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #80 on: July 08, 2019, 03:01:34 pm »
All this work to make buggy and unmaintainable code.  %)
You mean C of course, I presume? :o ;D
also related to equus asinus.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2282
    • havefunsoft.com
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #81 on: July 08, 2019, 03:59:27 pm »
I'd treat it as a task of the library interfacing in the first place.
If such structure is encountered in a C header, it should be known what and how to be handled in Pascal.

I can actually see the counter example in Pascal.
For RTL standard "file" operations. Where a user can declare a "file of XXXX", and then access the file as an array of records.
But most of the file formats (since start of the random-access disk era), don't use "strict-array" like structure. The internal files structure is typically more complex.
So using Pascal functions to read a binary file is now pretty much limited to "file of byte". (TStream)

All this work to make buggy and unmaintainable code.  %)
You mean C of course, I presume? :o ;D
from C perspective this actually making a less buggy code as the offset calculation is now compiler's responsibility.
« Last Edit: July 08, 2019, 04:02:52 pm by skalogryz »
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7503
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #82 on: July 08, 2019, 04:04:32 pm »
from C perspective this actually making a less buggy code as the offset calculation is now compiler's responsibility.

Only if you don't have to do any bounds checking. (IOW are absolutely sure that the range of elements you check are actually in the buffer.

Otherwise you need to do boundschecking, and get the two different counters (index in sizeof(entry)+offset for via record acces, and just bytes for the nr of bytes read into the buffer).

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2282
    • havefunsoft.com
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #83 on: July 08, 2019, 04:18:05 pm »
Only if you don't have to do any bounds checking. (IOW are absolutely sure that the range of elements you check are actually in the buffer.
...
Not using flexible array member still requires doing the same bounds checks.
+ some extra care for referencing the "data part" of the structure.
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

PascalDragon

  • Hero Member
  • *****
  • Posts: 673
  • Compiler Developer
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #84 on: July 09, 2019, 09:03:44 am »
All this work to make buggy and unmaintainable code.  %)
Again, this is required when one wants to conveniently interface with external libaries (e.g. WinAPI), especially if one does not want to deviate from the original record (or the documentation in case of MSDN) too much.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 635
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #85 on: July 09, 2019, 02:03:56 pm »
I am happy to say it would be quite hard to make a Free Pascal interface for my early C programs. Simply because if your only tool is a pointer, and the only libraries you have are stdio and stdlib, you indeed need to become creative. Especially because I did the UI and liked windows and menus (no mice yet). So they were borderline OOP, but in a weird way.

I mean, you could use pointers as well of course, but I doubt most standard container types would map. They weren't invented yet. But I almost always make my own Pascal-like strings, even on microcontrollers, as I hate the C ones. They would be easy to convert.


lucamar

  • Hero Member
  • *****
  • Posts: 2080
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #86 on: July 09, 2019, 02:47:29 pm »
But I almost always make my own Pascal-like strings, even on microcontrollers, as I hate the C ones. They would be easy to convert.

Ha! That was one of the first things I did on starting with C: build a (Turbo)Pascal-style string library. :)

Guess most "pascalers" moving to C did that :D
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

kwer

  • New Member
  • *
  • Posts: 11
  • Its my fortune to have it, its my fate to lose it.
----------------------------------
Duolong, please render me a fastest horse, I must  leave now!
----------------------------------

jamie

  • Hero Member
  • *****
  • Posts: 2083
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #88 on: July 11, 2019, 11:13:30 pm »
it would like PASCAL like if they would simply allow a sizeless field...

Number 1 at blue screen app creations!

PascalDragon

  • Hero Member
  • *****
  • Posts: 673
  • Compiler Developer
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #89 on: July 12, 2019, 09:12:31 am »
it would like PASCAL like if they would simply allow a sizeless field...
Code: Pascal  [Select]
  1. type
  2.   TMyRecord = record
  3.     a, b: DWord;
  4.     c: record end;
  5.   end;
There you have a field with size 0. And now?