Lazarus

Programming => General => Topic started by: 440bx on July 06, 2019, 03:01:06 am

Title: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 06, 2019, 03:01:06 am
Hello,

In C, it is possible to define a structure as follows:
Code: C  [Select]
  1. typedef struct mystruct
  2. {
  3.   DWORD a;
  4.   DWORD b;
  5.   DWORD c[];
  6. };
  7.  
The part that is notable is the definition of the field "c" as an array of DWORDs and that this array takes no space in the structure.  It is just there to allow the programmer to reference that location (after variable b).

Is there a way in FPC to declare a field in a record that takes no space and is there only to provide a way to reference that location in the record ?

Thank you for your help.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: skalogryz on July 06, 2019, 03:10:22 am
It's a flexible array member
https://en.wikipedia.org/wiki/Flexible_array_member

Is there a way in FPC to declare a field in a record that takes no space and is there only to provide a way to reference that location in the record ?
No. The "static" part should become the record. The flexible part should be read separately.

You can however, declare an additional structure that would cover for "flexible array member".
Code: Pascal  [Select]
  1. mystruct = packed record
  2.   a,b: DWORD;
  3. end;
  4.  
  5. mystruct_full = packed record
  6.   hdr : mystruct;
  7.   c : array[byte] of DWORD;
  8. end;
  9.  
as a result you can access "c" array using mystruct_full, BUT
you'll run into a range-check error, (if these are enabled), whenever you'd access c[] outside of declared boundaries (in this case it's "byte", but you could set it to "word")

also, sizeof(mystruct_full)   would obviously be greater than sizeof(mystruct)
While sizeof(mystruct) between C and Pascal would match in this case.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 06, 2019, 03:39:43 am
No. The "static" part should become the record. The flexible part should be read separately.
Thank you.  I wanted to make sure I didn't know of some FPC feature that would allow an equivalent/parallel construction.

You can however, declare an additional structure that would cover for "flexible array member".
Code: Pascal  [Select]
  1. mystruct = packed record
  2.   a,b: DWORD;
  3. end;
  4.  
  5. mystruct_full = packed record
  6.   hdr : mystruct;
  7.   c : array[byte] of DWORD;
  8. end;
  9.  
as a result you can access "c" array using mystruct_full, BUT...
yes, that sounds right.  It works using "absolute" to overlay the full struct over the "truncated" struct.  I tried a typecast and FPC complained about it being an invalid typecast (absolute works, that's good enough.)

also, sizeof(mystruct_full)   would obviously be greater than sizeof(mystruct)
While sizeof(mystruct) between C and Pascal would match in this case.
Yes, there are some "details" that one must be careful with (such as size)

That was helpful, thank you again.

Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: engkin on July 06, 2019, 07:25:23 am
I find it unpleasant to have to define two records to achieve the same result of one structure in C. Not to mention the possibility of using the wrong size.

I would use:
Code: Pascal  [Select]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$ModeSwitch advancedrecords}
  5.  
  6. Type
  7.   mystruct = packed record
  8.   private
  9.     function Getc(i: integer): DWORD; inline;
  10.   public
  11.     a,b: DWORD;
  12.     property c[i: integer]: DWORD read Getc;
  13.   end;
  14.  
  15. function mystruct.Getc(i: integer): DWORD;
  16. begin
  17.   Result := PDWORD(@self.b)[1+i]; // or PDWORD(sizeOf(self)+pbyte(@self))[i] or ...etc;
  18. end;
  19.  
  20. var
  21.   a: array[0..5] of DWord = (0,1,2,3,4,5);
  22.   sample: mystruct absolute a;
  23.  
  24. begin
  25.   WriteLn('Size: ', SizeOf(mystruct));
  26.   WriteLn('a: ', sample.a);
  27.   WriteLn('b: ', sample.b);
  28.   WriteLn('c[0]: ', sample.c[0]);
  29.   WriteLn('c[1]: ', sample.c[1]);
  30.   WriteLn('c[2]: ', sample.c[2]);
  31.   WriteLn('c[3]: ', sample.c[3]);
  32.  
  33.   ReadLn;
  34. end.

As you can see, c does not occupy any memory.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 06, 2019, 07:37:48 am
I find it unpleasant to have to define two records to achieve the same result of one structure in C. Not to mention the possibility of using the wrong size.

I would use:
Code: Pascal  [Select]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$ModeSwitch advancedrecords}
  5.  
  6. Type
  7.   mystruct = packed record
  8.   private
  9.     function Getc(i: integer): DWORD; inline;
  10.   public
  11.     a,b: DWORD;
  12.     property c[i: integer]: DWORD read Getc;
  13.   end;
  14.  
  15. function mystruct.Getc(i: integer): DWORD;
  16. begin
  17.   Result := PDWORD(@self.b)[1+i]; // or PDWORD(sizeOf(self)+pbyte(@self))[i] or ...etc;
  18. end;
  19.  
  20. var
  21.   a: array[0..5] of DWord = (0,1,2,3,4,5);
  22.   sample: mystruct absolute a;
  23.  
  24. begin
  25.   WriteLn('Size: ', SizeOf(mystruct));
  26.   WriteLn('a: ', sample.a);
  27.   WriteLn('b: ', sample.b);
  28.   WriteLn('c[0]: ', sample.c[0]);
  29.   WriteLn('c[1]: ', sample.c[1]);
  30.   WriteLn('c[2]: ', sample.c[2]);
  31.   WriteLn('c[3]: ', sample.c[3]);
  32.  
  33.   ReadLn;
  34. end.

As you can see, c does not occupy any memory.
Yes, excellent idea.  The property "c" in Pascal becomes the offset marker "c" in the C struct.  That is really good. :)

Thank you!.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: engkin on July 06, 2019, 08:08:17 am
And if you are bothered by the verbosity of the previous Pascal property, and don't mind seeing pointers (I am sure you don't):
Code: Pascal  [Select]
  1.   mystruct = packed record
  2.     a,b: DWORD;
  3.     function c: PDWORD; inline;
  4.   end;
  5.  
  6. function mystruct.c: PDWORD;
  7. begin
  8.   Result := PDWORD(pbyte(@self.b)+sizeOf(self.b));
  9. end;

of course, you can still access "c" as an open array to read/write its values:
Code: Pascal  [Select]
  1.   sample.c[i] := i+1
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 06, 2019, 08:37:13 am
And if you are bothered by the verbosity of the previous Pascal property, and don't mind seeing pointers (I am sure you don't):
Code: Pascal  [Select]
  1.   mystruct = packed record
  2.     a,b: DWORD;
  3.     function c: PDWORD; inline;
  4.   end;
  5.  
  6. function mystruct.c: PDWORD;
  7. begin
  8.   Result := PDWORD(pbyte(@self.b)+sizeOf(self.b));
  9. end;

of course, you can still access "c" as an open array to read/write its values:
Code: Pascal  [Select]
  1.   sample.c[i] := i+1
I like this one even better :)

Thank you again!.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 06, 2019, 09:38:02 am
This is what we call a "buffer overrun".
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: engkin on July 06, 2019, 09:45:41 am
Intentional.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: PascalDragon on July 06, 2019, 10:29:41 am
This is what we call a "buffer overrun".
Not if the memory backing the record is intentionally large enough (of course you shouldn't use it as a stack variable, but only as a pointer). Such constructs are often encountered when dealing with C code (see the other thread where this was talked about).
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 06, 2019, 05:02:16 pm
With range check off... and I hope they never disable this feature because its going to cause a lot of translation
issues if they do....

Code: Pascal  [Select]
  1. TmyRecord = Packed Record
  2.     A:Dword;
  3.     Case Integer of
  4.       0:(B:Dword;);
  5.       1:(C:Array[-1..-1] of DWord);
  6.  end;                                      
  7.  

{$R-}
 MYRecordInstance.C[0..?]…..


 Doing this the size of the record it exactly 8 bytes to account for the A,B Dword and using a case like this..

It would be nice if Fpc had a C:Array[] of Dword; so that it can generate a location without an instance.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 06, 2019, 05:12:03 pm
Example of use

Code: Pascal  [Select]
  1. {$Push}
  2. {$R-}
  3.  M := GetMem(1000);
  4.  TMyRecord(m^).C[10] := 1;
  5.  FreeMem(M);
  6.  {$pop}                      
  7.  
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: marcov on July 06, 2019, 05:20:38 pm
An empty record is sometimes used to create such identifier at the end of the record, but it of course doesn't have the typing like in C. Pascal is not big on out of bounds accesses by design.

Code: Pascal  [Select]
  1. type
  2.   TDummy = record end;
  3.   mystruct =record
  4.               a,b :DWord;
  5.                c:Tdummy;
  6. end;
  7.  
  8. begin
  9.   writeln(sizeof(mystruct)); // prints 8.
  10. end.
  11.  
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 06, 2019, 05:30:46 pm
If you really want to program in Pascal like in C, use pointers. Don't rape the language.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 06, 2019, 05:36:14 pm
The example I present I've used many times in Delphi and generally It works  but it isn't perfect because
the previous type isn't always optimum to give you the same type size so you need to fool with the index
range to fix that..

 I think this feature of empty array definitions should be implemented because it would allow rangeless
accessing of the array and not create a body instance.

 C:Array[] of Dword; in a Record would be perfect but it would need to be the last and final type in the
record.
 Also one could just bundle a list of different types at the end which would all fall on the same address bounds
 C:Array[] of Dword;
 D:Array[] of Word;

etc.


Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 06, 2019, 05:38:13 pm

Posted by: SymbolicFrank
« on: Today at 05:30:46 pm »
Insert Quote

If you really want to program in Pascal like in C, use pointers. Don't rape the language.

You may think that, but C actually does have some value that should be supported In pascal, no matter
how you want to look at it.

 They don't need to use the same syntax but at least produce the same results.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 06, 2019, 06:08:58 pm
I'm an old fag. And autodidact, so I have no formal training. I figure everything out for myself.

So. About ten years ago, I was posting on tweakers.net, our largest national tech website, about object oriented programming.

Generally, when there's a new buzzword in computers, people ask me: are you using <fill in newest buzzword>? And I answer, that I don't. They tell me, that I'm old and really should use this, as everyone is doing it. It's the best new thing. When I look it up, there's a lot of noise and marketing. And after some investigation I think: "Ah, that's what they mean. I have been doing that for years. I didn't know that was how it is called."

So, there was this discussion on this website about OO programming, and I joined in. I had done that before it was called like that. Even before Borland Pascal had the Object type. And even in C. And they all told me that I was a moron, didn't understand anything about it, and that wasn't how it worked. For starters, they weren't called objects and didn't use pointers. They were called classes and used methods. And there was no linked list. There were only "object instances".

I tried to explain. And they ganged up on me. They figured I was a stupid, easy target. So I pulled out. I have really wondered multiple times if they were right and I didn't understand.

Anyway, back to C. 40 years ago, C was very basic. C and C++ also have lots of exceptions for many things. But it was popular because it was short and cryptic. It looked like a magic formula, for the uninitiated. Very macho.

The two things C and C++ have inherited form this, are a fascination with speed and that it is really easy to fuck up. It's much harder to do it right. Correctness is not a requirement of the language. But, they did grow up a bit. C got things like members (foo.bar, and even foo->bar). Stricter type checking. Better syntax checking. Lint. Etc. To make it harder to shoot yourself in the foot. Because, 40 years ago, programming in C was really hard to do right.

I just spend a month trying to prevent having to do a large project in C. And you guys want to add the worst things from C to Pascal, simply because C can do that. You want less restrictions, because it allows macho programming. And make it much easier to fuck up. While C and C++ (especially Microsoft and LLVM) try to make C and C++ much, much stricter, to prevent all that. They would rip all that out in an instant, if it wasn't for backward compatibility.

Edit: Interesting video: https://www.youtube.com/watch?v=QM1iUe6IofM (https://www.youtube.com/watch?v=QM1iUe6IofM)
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: Handoko on July 06, 2019, 06:20:47 pm
Calm don't sir.

I believe many C (and other languages) users here do not mean to make FPC less restricted.

I see thing differently. Many users from other languages found Pascal is great and they want to use it seriously. But they already have written many codes in their previous language. If they can't port their old codes to Pascal, it may become a barrier for them to use Pascal.

I read the thread and saw many suggestions for this issue. Sorry, but it looks ugly to me. I love the simple and clean syntax of Pascal. But think the other side, if Pascal can be easily to port from other languages, it will be a great advantage.

~ Peace ~
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 06, 2019, 07:23:16 pm
Ever wondered why almost all lessons about "Things you shouldn't do while programming" are about C++? Because most of the things they tell you not to do are C++ specific. You cannot do them wrong in most other programming languages.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: skalogryz on July 06, 2019, 07:34:53 pm
Ever wondered why almost all lessons about "Things you shouldn't do while programming" are about C++? Because most of the things they tell you not to do are C++ specific. You cannot do them wrong in most other programming languages.
note: flexible array member feature is not inherited in C++. It's C only feature.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 06, 2019, 07:38:39 pm
@Jamie,
@Marco,

Thank you for the alternatives you provided/mentioned.


@Handoko

Many users from other languages found Pascal is great and they want to use it seriously. But they already have written many codes in their previous language. If they can't port their old codes to Pascal, it may become a barrier for them to use Pascal.
Exactly!.  Thank you for stating the obvious which seems to be not quite obvious to some.


I read the thread and saw many suggestions for this issue. Sorry, but it looks ugly to me. I love the simple and clean syntax of Pascal.
Pascal's clean syntax is one of its nicest features.  There is usually a clean/Pascal way of implementing a feature found in another language.   A little pondering usually helps get there.  What's important is the desire and dedication to implement it nicely, that's what will make a difference.

But think the other side, if Pascal can be easily to port from other languages, it will be a great advantage.
Not only a great advantage for the Pascal language but, also for those who use it.


@SymbolicFrank

If you really want to program in Pascal like in C, use pointers. Don't rape the language.
Not only is that rather dramatic and over the top, the construction "<vartype> <array[]>" is in C, precisely to be able to obtain a pointer to the desired location within the struct without having to declare a space-consuming field to obtain it.

C and C++ also have lots of exceptions for many things. But it was popular because it was short and cryptic. It looked like a magic formula, for the uninitiated. Very macho.
I believe there is some [added word] truth to that but, the reason some people use C is because, whether cryptically or cleanly, there is usually a way to tell the compiler what you want and the compiler will usually generate decent code for it.  That is a _big_ advantage.  In the case of Windows specifically, the API is spec-ed in C.  That means that, so far, the only way to get access to the full API definition is by using C/C++.  Sometimes just that is enough to use C/C++ instead of Pascal/FPC.  When one is writing a program, the objective is to write the program, not to have to translate function headers and structs from C to Pascal - which in most cases is fairly quick but sometimes the Pascal translation is something that had to be shoe-horned because the language lacks some type description facilities.

The two things C and C++ have inherited form this, are a fascination with speed and that it is really easy to fuck up. It's much harder to do it right.
There is definitely some truth to that but, it's got its pros and cons.  A well optimized program that is snappy is often a pleasure to use (provided it's not riddled with bugs as a result of some ill-conceived optimizations.)

Correctness is not a requirement of the language.
You're right.   Correctness is a requirement of the _programmer_.  That said, it is true that C offers a very limited amount of help in that area.  That's one of the areas they _greatly_ improved in C++.  Type checking in C++ is at least as good as in Pascal.

And you guys want to add the worst things from C to Pascal, simply because C can do that. You want less restrictions, because it allows macho programming. And make it much easier to fuck up.
Not only that isn't the case, it is completely over the top.  Adding simple things like a zero-size field to use as a reference in a struct/record is not unclean in any way.  On the contrary, having that results in code that is much cleaner than the un-intuitive pointer manipulation you have to do when the feature is not available.

The bottom line is this: producing correct programs is the responsibility of the programmer, not the compiler's.  A compiler should provide as many clean constructs as possible to enable the programmer to describe data succinctly and accurately. 

The compiler should help find errors, not get in the way of programming.

While C and C++ (especially Microsoft and LLVM) try to make C and C++ much, much stricter, to prevent all that. They would rip all that out in an instant, if it wasn't for backward compatibility.
They are making it stricter for the compiler to be able to flag potential programming errors but, they are _not_ restricting what the compiler can do.  On the contrary, constructs such as "array[]" are fairly new and they are a much cleaner way  to provide an address to access the field than using "array[ANYSIZE]".


General comment:

From the posts I've read in the forum, I get the impression there are a significant number of Pascal programmers averse to using pointers and variable size structures.  That seems to have been encouraged by the compiler's effort to hide pointer dereferences.  Makes programming "cushy" but, ultimately, it's not a good thing because the "programmer" isn't aware of what is _really_ going on.

A lot of programs can be written without using pointers and/or variable sized structures but, there are programs where _not_ using pointers and/or variable sized structures results in code that is more complicated, usually very wasteful of memory and just as often far from performing as well as they could.  For the user of such a program, that results in an experience that usually leaves something to be desired.


Lastly ...

It would be nice if FPC supported the "array[]" construction.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: engkin on July 06, 2019, 07:49:18 pm
@SymbolicFrank, it is really not about C or C++. There are practical problems that can be solved in elegant way if you know the content of this thread.

The simplest example I can provide maybe the checksum field located at the end of a record of variable length. What's your preferred way to reach that field?

Another example is a DNS packet, it starts with a header like:
Code: Pascal  [Select]
  1.     TransactionID: Word;
  2.     Flags: Word;
  3.     QuestionsCount: Word;
  4.     AnswersCount: Word;
  5.     AuthorityCount: Word;
  6.     AdditionalCount: Word;

followed by Questions. Each like:
Code: Pascal  [Select]
  1.     Name: array[0..0] of char;  // sample value: #3www#6google#3com#0
  2.     &Type: Word;
  3.     &Class: Word;

Notice that the field Name is of variable length, how do you reach Type and Class?

Remember you might have more questions in this record. How do you reach other questions? Then it is followed by Answers. Again, each answer is like... etc.

You can not always choose not to have variable length record.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 06, 2019, 08:48:45 pm
Ok, the argument is: people don't want to change. If we want them to use Pascal, we have to make sure that they can continue programming as they did and reuse all their old code.

Know Lisp? There's an endless amount of things you can do in Lisp, that you cannot do in Pascal. Ok, it's not that popular anymore.

JavaScript. Very popular. Classes are the same as (anonymous) functions, and they're stored as text (or as p-code). Like with .NET WCF. Eval() can do lots of things that are impossible in Pascal.

C and C++ are some of the worst languages, but they're used most. So you should be able to program in Pascal just as you did in C and C++, and reuse all your old code.

Why? If you want to program in C or C++, program in C or C++! Not Hard!

If you want to use a programming language that protects you against 90% of the pitfalls of those languages, while still offering the same possibilities, use Object Pascal.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: skalogryz on July 06, 2019, 08:52:31 pm
It would be nice if FPC supported the "array[]" construction.
in what sense?
If you're looking for the option of "Flexible array member", I doubt it's possible from Pascal point of view.
In pascal arrays are always of the known size. (you can always run length() on an array)

In this sort of C-style declaration, the length is never known.

So your best option would be to use a pointer to a pointer to an array.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 06, 2019, 09:10:16 pm
Btw, My "cool down, level headed" approach:

If you have been there form the start, you know how it all works. Especially if you also did electronics. If I ask a current programmer, who is almost certainly building web apps: "Do you know how the HTTP protocol works?", then, after a while, they admit that they don't. And if they do, I'll ask them "Did you ever build your own HTTP server?". Very few answer "yes" to that question.

That's why SCRUM is popular. Instead of analyzing the project and making a design beforehand, you just pick something simple (most often a bit of GUI) and start building there. Who knows what will happen? It's a journey full of surprises! And that's why current software is very buggy and never works as expected. But it probably looks really cool.

So, imagine if you make those programmers use C++.  :D

Then again, there are a few die-hard, very experienced programmers out there who can program well in any language. And quite a lot of those hang out here. They want more, better and sharper tools. Just for the occasional convenience. But their apprentice will probably do all those things he shouldn't. And it's not hard for a fresh programmer to totally break an existing project.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 06, 2019, 09:16:39 pm
In pascal arrays are always of the known size. (you can always run length() on an array)
Not really.  In a dynamic array declaration, the dynamic array is a pointer to an array of unknown size.  The size is only known after using SetLength().

In this sort of C-style declaration, the length is never known.
Correct.  The purpose is simply to mark the start of the array.  It's very similar to a dynamic array declaration, the only difference is that in a dynamic array declaration space is reserved to hold a pointer to the array.  In a construct such as "array[]" the compiler would have the address of the array as an offset into the record just as it does for any other field.

Unless I am missing something, I think it would be easy to implement, just one more offset into the symbol table and no storage reserved for the symbol's type.  It would probably be a good idea to restrict such a definition to field records since that's probably the only place where they make sense.


@SymbolicFrank

If we want them to use Pascal, we have to make sure that they can continue programming as they did and reuse all their old code.
No.  (more later)

Know Lisp? There's an endless amount of things you can do in Lisp, that you
cannot do in Pascal. Ok, it's not that popular anymore.

JavaScript. Very popular. Classes are the same as (anonymous) functions, and they're stored as text (or as p-code). Like with .NET WCF. Eval() can do lots of things that are impossible in Pascal.
You're comparing Ducks, Tricycles and Bushels of oranges.  The functional purpose of those languages differ greatly.  Pascal isn't JavaScript and was not designed to do what JavaScript does.

As far as Eval(), if you build in a full Pascal interpreter into your program, it will do everything eval() can do (of course, with the same limitations eval() has in other languages.)


C and C++ are some of the worst languages, but they're used most. So you should be able to program in Pascal just as you did in C and C++, and reuse all your old code.
But the fallacy you've built is that there is no purpose similarity between Pascal and C/C++.  Unlike with JavaScript, there is plenty and, whatever - desirable - features are present in C/C++ could be added to Pascal (often requiring some cleanup in the process.)

Why? If you want to program in C or C++, program in C or C++! Not Hard!
Here is another thing that's not hard.  If you want to program in a better language than C/C++, program in Pascal and slowly add to the Pascal language the useful features found in C/C++ removing the many "warts" in the process.

Eventually, you end up with a well designed language that has every feature needed to program a check book balancing program or a full blown operating system.  That would be very nice.

It seems some people don't like to see features they don't know how to use in a language.


If you want to use a programming language that protects you against 90% of the pitfalls of those languages, while still offering the same possibilities, use Object Pascal.
Good line for a commercial but, if you want to write a capable operating system, use C. 


Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 06, 2019, 10:07:38 pm
440bx, did you watch the video I linked? I'm pretty sure you'll totally agree. I leave it open if I do  ;)
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: skalogryz on July 06, 2019, 10:17:14 pm
Not really.  In a dynamic array declaration, the dynamic array is a pointer to an array of unknown size.  The size is only known after using SetLength().
dynamic arrays are managed types. Thus would be set to nil with zero size.

The compiler needs to release dynamic array safely, no matter if SetLength was called or not.

In Pascal the size of array is (must be) always known.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 06, 2019, 10:27:29 pm
@SymbolicFrank

440bx, did you watch the video I linked? I'm pretty sure you'll totally agree. I leave it open if I do  ;)
What link are you referring to ? ... maybe I missed it but, I don't see a link anywhere. 

Could you please post the link again ?... I will definitely watch it.

@skalogryz

In Pascal the size of array is (must be) always known.
I used the dynamic arrays as an example because it has similarities with "array[]".  There is no reason for the size of an array to always be known and even now, in FPC, there are arrays of unknown size, specifically, any typed pointer can be used as an array reference.  FPC already sees pointers the same way as C, as the address of an array.

That statement that in Pascal the size of an array is/"must be" always known isn't really true.  The way FPC treats/uses pointers breaks that rule.  It basically already sees typed pointers as an array[] declaration.


Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 06, 2019, 10:35:49 pm
This one: https://www.youtube.com/watch?v=QM1iUe6IofM (https://www.youtube.com/watch?v=QM1iUe6IofM)
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 06, 2019, 11:01:17 pm
That video is absolute garbage..
I like both methods of coding but when it comes to managing multiple items of the same thing you can not
beat OOP.
 
 I've done the way of creating multiple forms without OOP and it gets to be a mess!
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 06, 2019, 11:46:51 pm
I like both methods of coding but when it comes to managing multiple items of the same thing you can not
beat OOP.
Nope.  I think the only thing that might not beat OOP is honest-to-goodness totally out of control, full blown, spaghetti code. That _might_ be worse.

I've done the way of creating multiple forms without OOP and it gets to be a mess!
I believe you.  That's usually what people who don't know how to do it end up creating. 

That video is absolute garbage..
Your reaction is quite typical unfortunately. He makes quite a few good points.  He also missed quite a few of them but, he is much more often right than wrong.

For the record, I only listened to it, I didn't watch it.  I have no idea if he showed something I would consider wrong.


@SymbolicFrank

This one: https://www.youtube.com/watch?v=QM1iUe6IofM (https://www.youtube.com/watch?v=QM1iUe6IofM)

Thank you.  It's nice to know not everyone has been infected by OOP.

Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: skalogryz on July 07, 2019, 12:12:11 am
I used the dynamic arrays as an example because it has similarities with "array[]".  There is no reason for the size of an array to always be known and even now, in FPC, there are arrays of unknown size, specifically, any typed pointer can be used as an array reference.
There are three reasons on top of my head, why the size of an array always have to be known:
1) length() - has to return something. The function has to run on anything declared as an array and must return something
2) rangechecks - which are applicable to anything declared as an array.
3) passing an array to another routine (as an open array)
So, while there are syntax similarities, the semantic is different.

FPC already sees pointers the same way as C, as the address of an array.
you're right. Both treat pointers identically.
But what you're referring to is pointer math, not arrays.
Arrays in C are pretty much pointers. Arrays in Pascal are arrays (with a range, meaning the size is known).

The Pascal language itself still allows you to get C-like behavior (as shown multiple times on the page 1)
but doesn't do that automatically in any manner (by not providing a similar functionality of an array of unknown size)
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: ASerge on July 07, 2019, 12:28:55 am
Code: Pascal  [Select]
  1.   mystruct = packed record
  2.     a,b: DWORD;
  3.     function c: PDWORD; inline;
  4.   end;
  5.  
  6. function mystruct.c: PDWORD;
  7. begin
  8.   Result := PDWORD(pbyte(@self.b)+sizeOf(self.b));
  9. end;
A tiny bit faster:
Code: Pascal  [Select]
  1.   mystruct = packed record
  2.     a,b: DWORD;
  3.     function c: PDWORD; inline;
  4.   strict private
  5.     cStart: record end;
  6.   end;
  7.  
  8. function mystruct.c: PDWORD;
  9. begin
  10.   Result := PDWORD(@cStart);
  11. end;
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 07, 2019, 01:33:00 am
@skalogryz

There are three reasons on top of my head, why the size of an array always have to be known:
1) length() - has to return something. The function has to run on anything declared as an array and must return something
2) rangechecks - which are applicable to anything declared as an array.
3) passing an array to another routine (as an open array)
So, while there are syntax similarities, the semantic is different.
Here are my thoughts on that:

1) length() would always return zero just as it does for a dynamic array before SetLength() has been called to allocate memory for it.

2) rangechecks on such an array is not applicable since there is no range associated with the array.  IOW, whether rangechecks are enabled or not, the compiler would not enforce them on that kind of array since it does not have the information necessary to do any range checking.  For arrays of that kind, range checking would simply ignore them (as it should since it is the programmer's responsibility to ensure there are elements in the range he/she is accessing.)

3) if such an array were to be passed as an open array, the compiler would pass -1 for the element count (what high(array) currently does for an unallocated dynamic array).  The only difference with a dynamic array is that the count of elements isn't kept in a variable, as far as the compiler is concerned, it is always zero by definition.


FPC already sees pointers the same way as C, as the address of an array.
you're right. Both treat pointers identically.
But what you're referring to is pointer math, not arrays.
Arrays in C are pretty much pointers. Arrays in Pascal are arrays (with a range, meaning the size is known).

The Pascal language itself still allows you to get C-like behavior (as shown multiple times on the page 1)
but doesn't do that automatically in any manner (by not providing a similar functionality of an array of unknown size)
Arrays in both C and FPC are pointers (and any language that supports calculating an address based on an element's size.)  The operations allowed differ based on how those pointers are declared, which can be as a pointer with a range (e.g, array[low..high] of something, commonly thought of as an array) and a pointer without a range (p : pchar; just a pointer.)

The distinction between a pointer and an array is really artificial.


@ASerge,

Code: Pascal  [Select]
  1.   mystruct = packed record
  2.     a,b: DWORD;
  3.     function c: PDWORD; inline;
  4.   strict private
  5.     cStart: record end;
  6.   end;
  7.  
  8. function mystruct.c: PDWORD;
  9. begin
  10.   Result := PDWORD(@cStart);
  11. end;

Faster or not, that is very clean.  Very nice, thank you!.

Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: skalogryz on July 07, 2019, 02:18:58 am
Here are my thoughts on that:
1) ...
2) ...
3) ...
in that case you don't have an array. Or an array is always of a zero size.
Which makes it pretty useless.

The distinction between a pointer and an array is really artificial.
in your case you should really stick to the plain typed-pointer type, rather than array[] of any sort.

FPC allows you to use pointers in array-like manner.

Code: Pascal  [Select]
  1. var
  2.   a : PDword;
  3.   b : array [0..2] of DWORD;
  4. begin
  5.   b[0]:=0;
  6.   b[1]:=100;
  7.   b[2]:=200;
  8.  
  9.   a := @b[0];
  10.   writeln(a[1]);
  11.   writeln(a[2]);
  12. end.
  13.  
output:
Code: [Select]
100
200
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 07, 2019, 02:31:07 am
Here are my thoughts on that:
1) ...
2) ...
3) ...
in that case you don't have an array. Or an array is always of a zero size.
Which makes it pretty useless.
No, it is not useless.  It is quite a simple and useful way of marking the start of an array in a variable size record.  The array can be populated just like any array.  If a programmer tells the compiler
Code: Pascal  [Select]
  1. a[x] := somevalue;
all the compiler has to do is calculate the offset from "a" and stick "somevalue" in there.  It is no more complicated than that and, it already knows how to do it, all it needs is for the programmer to tell it where (the address of) the array is.

Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: skalogryz on July 07, 2019, 02:48:23 am
but this is what typed pointer is already doing
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: VTwin on July 07, 2019, 05:36:06 am
This one: https://www.youtube.com/watch?v=QM1iUe6IofM (https://www.youtube.com/watch?v=QM1iUe6IofM)

That was 45 minutes of my life I will never get back. Yes, I have many libraries with thousand of functions that operate on simple data types such as arrays or matrixes. The multiplication of matrixes, the solution of linear equations, or finding eigenvalues does not require OOP. But OOP simplifies many problems, if I have 10 plots to draw that share 80% of the codebase, that is a no brainer.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 07, 2019, 06:02:41 am
That was 45 minutes of my life I will never get back.
That's funny. It doesn't matter how you spend any minutes of your life, you'll never get them back no matter how you spent them.

But OOP simplifies many problems, if I have 10 plots to draw that share 80% of the codebase, that is a no brainer.
There are lots of bad programming practices that simplify things, for instance, global variables but, it doesn't mean they are good.  The thing they all have in common is that the cost of the simplicity they bring is paid in complexity in another area but, if one chooses to ignore their cost then, they are great.

The guy in that video is right but, no one is going to listen. He might as well be talking to a wall.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: VTwin on July 07, 2019, 06:34:25 am
That was 45 minutes of my life I will never get back.
That's funny. It doesn't matter how you spend any minutes of your life, you'll never get them back no matter how you spent them.
Thanks, I'm glad you appreciated my joke.

But OOP simplifies many problems, if I have 10 plots to draw that share 80% of the codebase, that is a no brainer.
There are lots of bad programming practices that simplify things, for instance, global variables but, it doesn't mean they are good.  The thing they all have in common is that the cost of the simplicity they bring is paid in complexity in another area but, if one chooses to ignore their cost then, they are great.

The guy in that video is right but, no one is going to listen. He might as well be talking to a wall.
Everyone is free to avoid OOP and use old school FORTRAN, C, Pascal, etc. I find it useful though.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 07, 2019, 09:10:59 am
Yes, I also think that OOP is one of the best tools we have. You just have to know how to use it.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 07, 2019, 09:58:25 am
You just have to know how to use it.
That's what OOP programmers tell themselves to feel good.  Those who realize how bad that thing is just don't know anything, it's so much easier that way.

That guy in the video proves the adage "There's none so deaf as those who will not hear."
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: marcov on July 07, 2019, 10:37:08 am
That video is absolute garbage..
Your reaction is quite typical unfortunately. He makes quite a few good points.  He also missed quite a few of them but, he is much more often right than wrong.

He has some sidepoints that IMHO should lead him to the conclusion that anything driven to extremes just invites trouble. (like if you should invite an overarching OO structure into your OS)

As a result, he just goes to a different extreme, and falls of the rails.

And yes, the video is crap, excrement etc. At least the first few minutes that I could bear. Too much unrelated cases, too much paranoia, too other unrelated stuff dragged in by the hairs.

If you want to make a point about OOP vs procedural, make a point based on building an application in either. Leave out the bosses, winapi, and US-as-a-nazi states pictures etc. (that was when I stopped watching, but I was already skipping ahead). Simply because it is irrelevant and not the level where most people work (and I doubt he has experience on that level either). Stick to what you (and your viewers) hopefully intimately know.

I also think the state minimization argument is weak. That is not a unique aspect of procedural programming, other than that it nowadays attracts minimalists that bother. (Well at least they upgraded from asm. Took only 40 years)

If tomorrow OOP becomes the minimalists next sweet spot, I'm sure they'll use the same arguments :-)

One of the first shots was the most interesting, but afaik he didn't delve deeper into it. I do often feel that information hiding/encapsulation (and then specially investing heavily in _language level_ encapsulation by default) is the least necessary part of OOP practices.

Specially in one (major) programmer projects, people always drone on on how in the future multiple other people might use the codebase and benefit from it, but my experience is that an aspect of the codebase is not stressed on a daily basis, the quality of it (iow classifying encapsulation visibility of fields/methods) will be very low.

OO should be about modelling and design, the language features are only helpers. People tend to overfocus on them.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 07, 2019, 10:54:12 am
Yes, making a property out of everything isn't mandatory. A public field will do in many cases. Just make it a property if you need to do some bookkeeping when accessing it. And a setter with just reading the field is often a good compromise.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: Handoko on July 07, 2019, 11:18:08 am
Sorry of being off topic.
Or maybe I should start a new thread.

I am an autodidact and programming is not my real job, so my knowledge is very limited.

Long years ago, in the era of 80 x 25 text mode I was thinking to build my own TUI. I knew Turbo Vision but I never learned how to use it. I like do something challenging, I decided to build my own version of turbo vision. I've just finished to learn single/double linked list, pointer, direct vga memory mapping, etc but I haven't known OOP. No matter how hard I tried, I just can't figure out how to build my TUI module.

Not until I found OOP. I got a book, which teaches you how to build your own simple Turbo Vision using C++. I can't use C/++ but from the book I learned the concept of OOP. Not long later I really managed to build my own TUI. It maybe not good as the others, but it works and looking good in my eyes. As a creative person, I added some animation effects and audio.

In my school age, I had plenty of time. But now, I have very limited time for programming. Currently I'm building my own OpenGL-based GUI using OOP concept.

I like OOP because it really helps me to solve some complicated cases. But I don't abuse it, I won't use it if it is not really needed. I believe everything good can become bad if you misuse it.

I often hear some said OOP is bad. But their explanations are out of my ability to understand. My glGUI progress is slow because I have limited time for working on it. I am neutral, I'm not a OOP fanatic but I can't write GUI without using OOP.

What I want to ask is:
Can anyone write me a simple code of GUI or TUI module without using OOP?

So I can learn from the code and rewrite my glGUI without using OOP. By experience it myself I can understand how good or bad OOP is.

I'm sure writing GUI module without using OOP is possible but I believe it should be very hard. Please prove me wrong.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: marcov on July 07, 2019, 11:28:43 am
It is possible. One guy had even a near complete professional GUI CAD program in the Mac dialect.

His parameter lists were awfully long though, and he used ISO style procedure callbacks (where procedures can pass a nested procedure to a callbacks which then can use the outer procedure/variables). The callbacks are effectively virtual methods.

Before I used language OO, I already used  OO in a way too in procedural programming. Grouping things into records, functions that always take such record as first parameter.  Records with callbacks in them.  etc.

Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: julkas on July 07, 2019, 11:34:09 am
@Handoko Clear and argumented post. Agree. +5.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: lucamar on July 07, 2019, 11:35:11 am
What I want to ask is:
Can anyone write me a simple code of GUI or TUI module without using OOP?

So I can learn from the code and rewrite my glGUI without using OOP. By experience it myself I can understand how good or bad OOP is.

I'm sure writing GUI module without using OOP is possible but I believe it should be very hard. Please prove me wrong.

There wer lots of TUI frameworks and components way before Borland "invented" TurboVision. TurboPower had their own, and there were TechnoJock's Toolkit, and quite a lot more, even as far back as Turbo Pascal 3. And that's not counting the "screen generators", or the frameworks for other Pascals, like the ones for Pascal MT+, JRT, etc.

And the same for GUIs. Once TP for Windows appeared everyone started adapting their TUIs and building encapsulations for the Windows API. Although that was on the era of TP6, when objects where already quite stablished and Turbo Vision was ... almost king, so a lot of effort went towards building "Windows Vision"s :)

And then came Delphi and it ruined it all :D
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 07, 2019, 11:38:57 am
If you want to see how to program a GUI without OOP, look at Win16. Well, behind the screens that still works today, but you really don't want to do that.

My previous job was bugfixing a 25 years old C++ Windows app, and I added stuff like unicode controls, drag-and-drop, etc. So I had to do that the old way. It is complex, error prone and a lot of work.

Edit: Of course I encapsulated that into some nice classes to use it.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: Peter H on July 07, 2019, 11:59:09 am

I often hear some said OOP is bad. But their explanations are out of my ability to understand. My glGUI progress is slow because I have limited time for working on it. I am neutral, I'm not a OOP fanatic but I can't write GUI without using OOP.

What I want to ask is:
Can anyone write me a simple code of GUI or TUI module without using OOP?

So I can learn from the code and rewrite my glGUI without using OOP. By experience it myself I can understand how good or bad OOP is.

I'm sure writing GUI module without using OOP is possible but I believe it should be very hard. Please prove me wrong.

I believe, a GUI or a GUI item is an object, like most external devices, might it be a CNC machine, a printer or a moon rocket...
It has an internal state (member variables) and these must store and reflect the state of the external object and for this handler procedures are used.
Usually these routines are not reentrant, because the external object is not reentrant.
So if you do it with a non-objectoriented language, then you must mimic object orientation.
If typeextending and inheritance is needed, then you must use typecasting.....

BTW, I am autodidact too and I did embedded programming in C and assembler wrote software to control and visualize a high pressure autoclav, in Turbo Pascal 30 years ago. There was no internet and I learned out of books and journals. I got no formal education but formal selfstudy and got my education on the job.
But I had formal education on electronics.
And sometimes it is important to know the problem that has to be solved. All formal education doesnt help if you have to solve a problem that you dont understand, this is why most drivers for UARTs are buggy.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: PascalDragon on July 07, 2019, 12:33:19 pm
It would be nice if Fpc had a C:Array[] of Dword; so that it can generate a location without an instance.
No. This feature would only have a rather restricted use (namely as the last field of records) and as others demonstrated there are solutions that make use of existing language features to provide the same result. They might involve a bit more typing, but they work now.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: marcov on July 07, 2019, 03:17:04 pm
It would be nice if Fpc had a C:Array[] of Dword; so that it can generate a location without an instance.
No. This feature would only have a rather restricted use (namely as the last field of records) and as others demonstrated there are solutions that make use of existing language features to provide the same result. They might involve a bit more typing, but they work now.

And that style was popular 20-30 years ago, and is enshrined in the apis from that era. But I'm not sure that much new code in this style is written. (as in trying to access variable number items via the header record in front of them)

Probably it invites not writing safe code.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 07, 2019, 04:31:06 pm
So I guess the juror have tallied their votes.

 They would rather use twisted hacks that makes it readable only by those that know the code inside/out, if they
can successfully get it to work in a particular instance thus making it hard to read by those that would like the see a nice straight forward approach.

 The lot of you may not like the C approach but this I can tell you, its a lot cleaner and simpler to understand
over what hacks, if workable, that are offered here.

 There are some things in C that are clearly laid out no matter how old they are. Other languages do not
need to copy the syntax but they should be able to offer a straight solution to it.

 So I've seen here so far, over lapping Records which requires more work to implement and less readable.

 I've seen some undocumented use of an Empty Record which is fine but it still needs a type cast over it
to take advantage of it and maybe helper functions. Still way too much code and very unreadable afterwards.


 And then I offered the -1..1- offset array in the variant record which does work in most cases but I am
reading articles on the bug site that indicate not being able to index them out of range even with
range checking off in coming releases of fpc.

 So what's it going to be, a campaign to ensure fpc makes everyone's life a wreck when implementing
techniques that are only possible in other languages ?

 You can improve fpc without loosing the pascal language interface.. Personally I hate C and Especially
C++ in many cases, but there so cavets to the language..

Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 07, 2019, 04:58:14 pm
You can always do it yourself.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 07, 2019, 05:10:21 pm
I don't want a personized version of fpc for myself.

I want one that offers equal solutions that everyone can use..

I don't consider myself as a selfish person so why would I have a pascal compiler onboard that
only "I" can use, I would like the community to be able to share in the fruits of advancement without
loosing their love for the Pascal verbosity syntax.

 I am sure you can understand that but if one would just sit down and take a good long look at the
language differences, the good and the bad, with a few and only a very few additions to Fpc, it would motivate
a lot of other language users over to fpc advanced version of pascal.

 I work in C/C++ at work and like I said there some things that are greate about it, but over all when it
comes to working with Classes/Objects, I'll pick Pascal/Fpc any day and there aren't many C/C++ out there
that have RAD interfaces. I have Builder on board but its kind of dated but use it to maintain some apps only
because I was asked to do it that way instead of Delphi years back.

 The guide lines of tighten the rope around coders necks for type-ness ect can endup biting you in the long run.



Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: marcov on July 07, 2019, 05:14:20 pm
I've seen some undocumented use of an Empty Record which is fine but it still needs a type cast over it
to take advantage of it and maybe helper functions. Still way too much code and very unreadable afterwards.

That was me, and it was answer to a direct question how to create an empty symbol at the end. I don't use it in production code, it is something from unittests checking record sizes etc.

Personally I think that the savings are very low, or even not existing. Specially since there probably is already some pointer to where you are in the buffer that can be incremented. (this kind of structures is mostly used to decode buffers, like a fileheader and some variable entries, used in e.g. CHM).  9 times out of ten you need to do anything anyway, to proper check your buffer boundaries, so the savings are only in very simplistic cases.

p.s. the best thing about C: if somebody whines for an extension they probably get the answer: sure, write a paper to present for the future standard C '24 or so.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: Thaddy on July 07, 2019, 05:16:52 pm
Defining sub types of a variant record as variant record themselves is actually more readable than C(++) union syntax, because the type is defined more precise. And can be in any order.,
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 07, 2019, 05:47:48 pm
The lot of you may not like the C approach but this I can tell you, its a lot cleaner and simpler to understand over what hacks, if workable, that are offered here.

There are some things in C that are clearly laid out no matter how old they are. Other languages do not need to copy the syntax but they should be able to offer a straight solution to it.

So I've seen here so far, over lapping Records which requires more work to implement and less readable.
Those are good points and I share your viewpoint (which, just like yours, isn't worth anything) but.... the reality is and will very likely continue to be :
No. This feature would only have a rather restricted use (namely as the last field of records) and as others demonstrated there are solutions that make use of existing language features to provide the same result. They might involve a bit more typing, but they work now.
Making something simpler, cleaner, easier to read and understand is not what drives the inclusion of a feature in FPC.   It gives the impression that the people who are responsible for updating the C standard are just producing useless things no one needs. 

Bottom line is: be content there is a way of doing it.  That's in most cases all you're going to get along with a "bonus" like "+=" or ">>" and some other thing like that, you have absolutely no need for.  To keep you away from posting obvious improvements like you did, they'll change the semantics of some keyword (like "var" for instance") so it generates piles of useless hints you have to wade through.  That will keep you busy doing something "useful".


Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: Peter H on July 07, 2019, 06:15:27 pm
My two pence.
I believe this is pretty good selfdocumenting.
Of course it would be nicer, if this could be written inline as property. (I love properties ::) )

Code: Pascal  [Select]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeswitch advancedrecords}
  5.  
  6. type
  7.   mystruct = packed record
  8.   a,b: DWORD;
  9.   function c: PDWORD; inline; // return adress after record
  10. end;
  11.  
  12. function mystruct.c: PDWORD;
  13. begin
  14.   {$T+} // @ now gives typed pointers
  15.   c := PDWORD(@self+1);
  16. end;
  17.  
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: engkin on July 07, 2019, 06:45:50 pm
My two pence.
I believe this is pretty good selfdocumenting.
Of course it would be nicer, if this could be written inline as property. (I love properties ::) )

Code: Pascal  [Select]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeswitch advancedrecords}
  5.  
  6. type
  7.   mystruct = packed record
  8.   a,b: DWORD;
  9.   function c: PDWORD; inline; // return adress after record
  10. end;
  11.  
  12. function mystruct.c: PDWORD;
  13. begin
  14.   {$T+} // @ now gives typed pointers
  15.   c := PDWORD(@self+1);
  16. end;
  17.  

Code: Pascal  [Select]
  1. function mystruct.c: PDWORD;
  2. begin
  3.   {$Push}{$T+} // @ now gives typed pointers
  4.   c := PDWORD(@self+1);
  5.   {$Pop}
  6. end;
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: engkin on July 07, 2019, 06:54:46 pm
A tiny bit faster:
Code: Pascal  [Select]
  1.   mystruct = packed record
  2.     a,b: DWORD;
  3.     function c: PDWORD; inline;
  4.   strict private
  5.     cStart: record end;
  6.   end;
  7.  
  8. function mystruct.c: PDWORD;
  9. begin
  10.   Result := PDWORD(@cStart);
  11. end;
Thank you. I expected both to have the same assembly, but it seems there is an issue with constant folding in FPC 3.0.4?
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 07, 2019, 07:23:49 pm
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.  
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: engkin on July 07, 2019, 07:37:10 pm
So I guess the juror have tallied their votes.

There is a [better? easier?] way to get new features added to FPC. If you can get them added to Delphi.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: Handoko on July 07, 2019, 07:41:17 pm
There is a [better? easier?] way to get new features added to FPC. If you can get them added to Delphi.

Very true.  :D
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 07, 2019, 07:48:33 pm
Yes, I was thinking of that actually   >:D

But I don't really want to poke the bear!

It seems or I've read somewhere that Delphi did copy some of the fpc/Laz ideas for their product so
what are we waiting for, lets help them out!

all of this ridiculous hacking just to object a simple non entity C:Array[] of DWord at the end of the record..

In the old days and maybe still in asm we used

ORG. $AddressValue

I suppose with some compiler trickery we could get the "ABSolute" key word to generate an entity address
type and value for calling code.

Come to think about it I remember trying to implement a palette entry in the bitmap image and was a
problem doing that since the final array at the end of the bitmapHeader used the same technique and in
cases where there was no entrys you had to screw around with the code putting in extra check points in it.
 you couldn't take the C code for what it was and directly use it..


 
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 07, 2019, 08:19:34 pm

First, I want to thank all those who contributed some way of implementing that C construct.  There are some really nice ideas and implementations.

All the solutions so far, share the same problem which is, you cannot take the address of "c" or one of its elements i.e,
Code: Pascal  [Select]
  1. @c
  2. @c[x]


Because of that, the closest that allows taking the address of the flexible array seems to be:
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.  
The obvious problem with the above is, there is no "real" datatype associated with the array elements.  That in turn will require a typed pointer to access the elements of "c" and the typed pointer can be used to derive the address of any element.

I cannot think of a solution that would allow to specify the array element's type, which is necessary to derive the address of an element, without it changing the size of the record.


Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: Handoko on July 07, 2019, 08:55:27 pm
I want to thank all those who contributed some way of implementing that C construct.

Someone please document it on the wiki page. It can be valuable for new users coming from C.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 07, 2019, 08:57:07 pm
ah, but you can with what I used originally..
Code: Pascal  [Select]
  1. TMyRecord = record
  2.  A:DWord;
  3.  Case Integer of
  4.   0:(B:DWord);
  5.   1:(C:Array[-1..-1] of DWord;
  6. End;
  7.  

That should resolve to an address.
Untested;
Code: Pascal  [Select]
  1. {$R-}
  2.  @MyRecord.C[0];
  3.  
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: engkin on July 07, 2019, 09:19:35 pm
Someone please document it on the wiki page. It can be valuable for new users coming from C.
No way, we do not want them here.  >:D



That should resolve to an address.
Untested;
Code: Pascal  [Select]
  1. {$R-}
  2.  @MyRecord.C[0];
  3.  
Every time you touch MyRecord.C[ beautify it with:
Code: Pascal  [Select]
  1. {$Push}{$R-}
  2.  @MyRecord.C[0];{$Pop}
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 07, 2019, 09:23:48 pm
ah, but you can with what I used originally..
Code: Pascal  [Select]
  1. TMyRecord = record
  2.  A:DWord;
  3.  Case Integer of
  4.   0:(B:DWord);
  5.   1:(C:Array[-1..-1] of DWord;
  6. End;
  7.  



That should resolve to an address.
Untested;
Code: Pascal  [Select]
  1. {$R-}
  2.  @MyRecord.C[0];
  3.  

Jamie, you are correct.  That construct does allow taking the address _but_ it has one very significant downside, the bounds of the array have to be carefully set to overlap part of the fixed field definition and, in some cases, it may not even be possible to do that (when the size of the fixed size is not a multiple of the size of the array elements).

I appreciate your suggestion but, it has too many downsides to be used in practice.

Thank you though.

Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: marcov on July 07, 2019, 09:27:58 pm
It does get bonus points for creativity though  :)
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 07, 2019, 10:35:18 pm
Yes of course, That was the item I was referring to, if the previous type is the same size.

it does not work in all cases..

The other way to keep it pascal I guess would be to use overlapping records;
Code: Pascal  [Select]
  1. Type
  2. TmyRecordHdr = Record
  3.  A,B:DWord;
  4. End;
  5. TmyRecord = Record
  6.   H:TMyRecordHdr;
  7.   C:Array[0..0] of DWord;
  8. End;
  9.  

So we can use the RecordHdr for the most part but when you are ready to access the trailing data..
Code: Pascal  [Select]
  1. TMyRecord(MyReadhrInstance).C[?];
  2.  

I need to find some Delphi devs and hint them on..... >:D
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: engkin on July 07, 2019, 11:08:07 pm
I need to find some Delphi devs and hint them on..... >:D
Hitting two stones with one bird.  >:D
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx on July 07, 2019, 11:18:20 pm
I need to find some Delphi devs and hint them on..... >:D
I am not fond of being pessimistic but, it's rather unlikely to make a difference.  The result will most likely be along the lines of what you observed in this thread of yours https://forum.lazarus.freepascal.org/index.php/topic,43898.msg308122.html#msg308122 (https://forum.lazarus.freepascal.org/index.php/topic,43898.msg308122.html#msg308122)

Hitting two stones with one bird.  >:D
LOL... that either requires a large bird or the stones to be close together (or both!)

Code: Pascal  [Select]
  1. var
  2.   bird : packed array[1..2] of stone;
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: skalogryz 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
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: Handoko on July 08, 2019, 05:07:42 am
 :) Good, we make it one less reason C users can't port their codes to Pascal.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: 440bx 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.)
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: PascalDragon 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.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank on July 08, 2019, 11:11:42 am
All this work to make buggy and unmaintainable code.  %)
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: Thaddy 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
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: skalogryz 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.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: marcov 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).
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: skalogryz 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.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: PascalDragon 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.
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: SymbolicFrank 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.

Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: lucamar 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
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: kwer on July 11, 2019, 11:39:10 am
https://wiki.freepascal.org/Flexible_Array_Member
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: jamie on July 11, 2019, 11:13:30 pm
it would like PASCAL like if they would simply allow a sizeless field...

Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: PascalDragon 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?
Title: Re: Can this C struct be expressed in FPC Pascal ?
Post by: BrunoK on July 12, 2019, 11:16:13 am
There you have a field with size 0. And now?
This is code extract from my revisited heaptrc unit, specifically representing the structures involved in heap memory allocation :
Code: Pascal  [Select]
  1.  
  2. type
  3.   RObjclass_pvmt = record         // Must be multiple of 8 bytes, see below.
  4.     _object: TObject;            // The vmt of the allocated TObject descendent
  5. {$IFDEF CPU32}
  6.     locked_incr: longint;        // Global increment of GetMem
  7. {$ENDIF}
  8. {$IFDEF CPU64}
  9.     locked_incr: int64;          // Global increment of GetMem
  10. {$ENDIF}
  11.   end;
  12.   PObjclass_pvmt = ^RObjclass_pvmt;
  13.  
  14.   pheap_mem_info = ^theap_mem_info;
  15.  
  16.   pheap_extra_info = ^theap_extra_info;
  17.   theap_extra_info = record
  18.     exact_info_size: dword;  // exact_info_size as calculated in
  19.     fillproc: tfillextrainfoProc;
  20.     displayproc: tdisplayextrainfoProc;
  21.     sig: TSig;               // used to check if pheap_extra_info^ is still valid
  22. {$IFDEF CPU64}
  23.     sig_al64: dword;         // pad to align data on 16 bytes
  24. {$ENDIF}
  25.     Data: packed Record end; // variable sized array of byte
  26.   end;
  27.  
  28.   ppheap_mem_info = ^pheap_mem_info;
  29.  
  30.   { warning the size of theap_mem_info
  31.     must be a multiple of uintptr so processor that require
  32.     register load alignment on 4/8 bytes wont cause errors. }
  33.  
  34.   { theap_mem_info }
  35.  
  36.   theap_mem_info = packed record
  37.   public
  38.     previous,
  39.     Next: pheap_mem_info;
  40.     todolist: ppheap_mem_info;
  41.     todonext: pheap_mem_info;
  42.     size: ptruint;
  43. {$IFDEF TrackObjectClasses}
  44.     objclass_pvmt: RObjclass_pvmt;
  45. {$ENDIF}
  46.     sig: TSig;          // crc calculated signature
  47. {$ifndef EXTRA and defined(CPU64)}
  48.     sig_al64: dword;    // pad to reach 64
  49. {$ENDIF}
  50.     calls: array [1..tracesize] of codepointer;
  51.     extra_info_size: dword;  // SizeOf(theap_extra_info) +
  52.                              // SizeOftheap_extra_info desired .Data.size
  53.                              // 0 if no extra_info
  54.     VarRec : packed record
  55.       case Boolean of
  56.         False :
  57.           (mem_info : pheap_mem_info; // Back pointer to theap_mem_info record
  58.            data : record end);
  59.         True :
  60.           (extra_info : theap_extra_info);
  61.     end;
  62.     { Copies pre-allocated record to self }
  63.     procedure Initialize;
  64.     { Return the memory size requested to hold both theap_mem_info and Data
  65.         if Self <> nil returns the size that was previously allocated }
  66.     function NewAllocSize(aSize: ptruint): ptruint;
  67.     function calculate_sig : TSig;
  68.     { Retrieve pointer to the mem_info that sits in front of data }
  69.     function GetBackPointerP : pheap_mem_info; { inline; }
  70.     function HasExtraInfo : boolean;
  71.     { Retrieves place to plug deadbeef }
  72.     function TailPointer: PLongWord;
  73.     { Recalculate / adjust the VarRec.mem_info during GetMem and ReallocMem }
  74.     procedure UpdateBackPointer; inline;
  75.   end;
  76.  
Both " data : record end;" are used to do calculations about memory offsets in the variant record. The stuff is messy but using the record methods, the discomfort of working with variant sized records can be aleviated.

Example : calculate invariant part size of heap_mem_info (using empty record).
Code: Pascal  [Select]
  1.   heap_mem_info_inv_size := pointer(@aheap_mem_info.VarRec.data) - pointer(@aheap_mem_info);
  2.  
The getmem for the structure depends on its different parts.