Recent

Author Topic: [SOLVED] question about bit field alignment in FPC records  (Read 6616 times)

440bx

  • Hero Member
  • *****
  • Posts: 4037
[SOLVED] question about bit field alignment in FPC records
« on: July 08, 2019, 09:30:46 pm »
Hello,

In C, one can align the next set of bit fields in a struct to the next byte boundary by specifying 0 as the size of the bit field.

For instance, the following struct
Code: C  [Select][+][-]
  1.     typedef struct bitstruct              {
  2.        char   OneBit   :  1;
  3.        char   TwoBits  :  2;
  4.        char            :  0;
  5.        char   TwoBits2 :  2;
  6.        char   TwoBits3 :  2;
  7.    } thebitvar ;
  8.  
is of size 2 because "char : 0" causes the next two (trailing) fields to start at the next byte.

I tried doing that with FPC, as follows:
Code: Pascal  [Select][+][-]
  1. type
  2.   TALIGN = 0..0;
  3.  
  4.   TSomeBitLevelStructure2 = bitpacked record  // size = 1
  5.                                               // seems it should be 2
  6.     OneBit    : 0..1;
  7.     TwoBits   : 0..3;
  8.  
  9.     ZeroBit2  : TALIGN; // should align next bit fields to the next byte
  10.                         // but, it doesn't seem to do that.
  11.  
  12.     TwoBits2  : 0..3;   // shouldn't this bit be aligned on a byte boundary due
  13.     TwoBits3  : 0..3;   // to the ZeroBit2 field ?
  14.   end;
  15.  
but that resulted in a record size of 1 instead of 2. 

Interestingly, if I define the record as follows instead:
Code: Pascal  [Select][+][-]
  1.   TSomeBitLevelStructure3 = bitpacked record  // size = 2, this is ok
  2.  
  3.     OneBit    : 0..1;
  4.     TwoBits   : 0..3;
  5.  
  6.     ZeroBit   : TALIGN;
  7.     ZeroBit2  : TALIGN; // shouldn't this one be redundant ? (do nothing ?)
  8.  
  9.     TwoBits2  : 0..3;
  10.     TwoBits3  : 0..3;
  11.   end;
  12.  
The compiler reports the record size as 2 but, it would seem completely unnecessary - not to mention redundant - to have to specify the zero bit field twice.

Am I making some mistake someplace ?


Complete small sample program for testing purposes:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$LONGSTRINGS OFF}
  3.  
  4. program _BitFieldAlignment;
  5.  
  6. uses
  7.   windows,
  8.   sysutils
  9.   ;
  10.  
  11.  
  12. type
  13.   TALIGN = 0..0;
  14.  
  15.   TSomeBitLevelStructure1 = bitpacked record  // size = 1
  16.  
  17.     OneBit    : 0..1;
  18.     TwoBits   : 0..3;
  19.  
  20.     TwoBits2  : 0..3;
  21.     TwoBits3  : 0..3;
  22.   end;
  23.  
  24.   TSomeBitLevelStructure2 = bitpacked record  // size = 1
  25.                                               // seems it should be 2
  26.     OneBit    : 0..1;
  27.     TwoBits   : 0..3;
  28.  
  29.     ZeroBit2  : TALIGN; // should align next bit fields to the next byte
  30.                         // but, it doesn't seem to do that.
  31.  
  32.     TwoBits2  : 0..3;   // shouldn't this bit be aligned on a byte boundary due
  33.     TwoBits3  : 0..3;   // to the ZeroBit2 field ?
  34.   end;
  35.  
  36.   (* equivalent C struct - returns size = 2 (NOT 1 as FPC does)
  37.  
  38.     typedef struct bitstruct              {
  39.        char   OneBit   :  1;
  40.        char   TwoBits  :  2;
  41.        char            :  0;
  42.        char   TwoBits2 :  2;
  43.        char   TwoBits3 :  2;
  44.    } thebitvar ;
  45.  
  46.  *)
  47.  
  48.   TSomeBitLevelStructure3 = bitpacked record  // size = 2, this is ok
  49.  
  50.     OneBit    : 0..1;
  51.     TwoBits   : 0..3;
  52.  
  53.     ZeroBit   : TALIGN;
  54.     ZeroBit2  : TALIGN; // shouldn't this one be redundant ? (do nothing ?)
  55.  
  56.     TwoBits2  : 0..3;
  57.     TwoBits3  : 0..3;
  58.   end;
  59.  
  60.  
  61.  
  62. begin
  63.   writeln('size of TSomeBitLevelStructure1 : ', sizeof(TSomeBitLevelStructure1));
  64.   writeln('size of TSomeBitLevelStructure2 : ', sizeof(TSomeBitLevelStructure2));
  65.   writeln('size of TSomeBitLevelStructure3 : ', sizeof(TSomeBitLevelStructure3));
  66.  
  67.  
  68.   writeln;
  69.   writeln('press enter/return to end this program');
  70.   readln;
  71. end.

Thank you for your help.
« Last Edit: July 10, 2019, 11:41:24 pm by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: question about bit field alignment in FPC records
« Reply #1 on: July 08, 2019, 10:24:01 pm »
Beautiful Pure Pascal is readable, and does not need cryptic ugly "C"ism alignment indicators. In fact, you don't need to use bitpacked at all, as Pascal provides alternatives. Consider using bitwise operators: AND, OR, XOR. Probably "bitpacked" was added in a moment of weakness, just like +=, I say.

But if you insist, you have a few options: 1-You can use a few bitpacked records, and merge them into a packed record. 2-You can also fill the gaps with enough number of bits. There is an extra benefit with the second solution, you get to know exactly how many bits there are in these gaps.

As for:
Code: Pascal  [Select][+][-]
  1. type
  2.   TALIGN = 0..0;
it occupies one bit, just like:
Code: Pascal  [Select][+][-]
  1. type
  2.   TSample = 0..4;
occupies 3 bits.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11453
  • FPC developer.
Re: question about bit field alignment in FPC records
« Reply #2 on: July 08, 2019, 10:28:29 pm »
(Bitpacking structures is used really a lot in embedded targets, where peripherals registers are mapped using absolute bitpacked records/unions)

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: question about bit field alignment in FPC records
« Reply #3 on: July 08, 2019, 10:36:30 pm »
Thinking about even more, I come to the realization that even bitwise operators are not needed. You can achieve the same using shifting and logical operators. The language is full of unnecessary extensions just because people want to have their previous favorite language replicated in Pascal.  >:D

(Bitpacking structures is used really a lot in embedded targets, where peripherals registers are mapped using absolute bitpacked records/unions)
Yes, true. You probably recognize this structure

440bx

  • Hero Member
  • *****
  • Posts: 4037
Re: question about bit field alignment in FPC records
« Reply #4 on: July 08, 2019, 10:48:20 pm »
Beautiful Pure Pascal is readable,
I generally agree with that.

and does not need cryptic ugly "C"ism alignment indicators. In fact, you don't need to use bitpacked at all, as Pascal provides alternatives.
but Pascal lives in a C world.  The Windows API is spec-ed in C and there are structures that use "type : 0" to align to the next byte.  It is nice when there is a parallel construction since that eases the translation from C to Pascal.

Consider using bitwise operators: AND, OR, XOR. Probably "bitpacked" was added in a moment of weakness, just like +=, I say.
That's work the compiler can do for the programmer.  That's what a compiler is for, to work for the programmer.

But if you insist,
The Windows API "insists", not me.

1-You can use a few bitpacked records, and merge them into a packed record.
Thank you, that is one possibility.  It would be nice, if the struct definition didn't have to be broken into pieces to define it properly.

2-You can also fill the gaps with enough number of bits. There is an extra benefit with the second solution, you get to know exactly how many bits there are in these gaps.
Yes but, it is error prone.  Miscount the bits and the structure is wrong.  Compilers should count.

As for:
Code: Pascal  [Select][+][-]
  1. type
  2.   TALIGN = 0..0;
it occupies one bit, just like:
Code: Pascal  [Select][+][-]
  1. type
  2.   TSample = 0..4;
occupies 3 bits.
You're right.  I should have thought of that.  Wishful thinking on my part caused me to want to believe it was aligning.  My mistake.

Thank you for your help Engkin, I do appreciate it.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: question about bit field alignment in FPC records
« Reply #5 on: July 08, 2019, 11:08:24 pm »
Beautiful Pure Pascal is readable,
I generally agree with that.
I am glad we agree on something, because disagreements are about to happen.

and does not need cryptic ugly "C"ism alignment indicators. In fact, you don't need to use bitpacked at all, as Pascal provides alternatives.
but Pascal lives in a C world.  The Windows API is spec-ed in C and there are structures that use "type : 0" to align to the next byte.  It is nice when there is a parallel construction since that eases the translation from C to Pascal.
You are approaching this the wrong way. You should push to "Pascalize" Windows, and even quit using Windows or any other OS that uses C for that matter. Ban/Boycott/Bar C (BBBC) from your life.

Consider using bitwise operators: AND, OR, XOR. Probably "bitpacked" was added in a moment of weakness, just like +=, I say.
That's work the compiler can do for the programmer.  That's what a compiler is for, to work for the programmer.
Unsurprisingly, I disagree, again. The programmer should always be busy, always thinking, never lazy. It is a preventative precaution against Alzheimer at least. The effect of compilers taking burden of calculations on us mentally is bad. Similar to the effect of smartphones on our eyes. Just terrible.

But if you insist,
The Windows API "insists", not me.
BBBC, simple!

1-You can use a few bitpacked records, and merge them into a packed record.
Thank you, that is one possibility.  It would be nice, if the struct definition didn't have to be broken into pieces to define it properly.
Consider it like separation between church and state, or between data and user interface.

2-You can also fill the gaps with enough number of bits. There is an extra benefit with the second solution, you get to know exactly how many bits there are in these gaps.
Yes but, it is error prone.  Miscount the bits and the structure is wrong.  Compilers should count.
Error is human nature, accept it. Look at the full half of the cup: you know precisely how many bits there are in these gaps, because you had to recompile your code a few times to see if you counted them right this time. Plenty of pleasure when you finally do.

As for:
Code: Pascal  [Select][+][-]
  1. type
  2.   TALIGN = 0..0;
it occupies one bit, just like:
Code: Pascal  [Select][+][-]
  1. type
  2.   TSample = 0..4;
occupies 3 bits.
You're right.  I should have thought of that.  Wishful thinking on my part caused me to want to believe it was aligning.  My mistake.
Wishful thinking is just bad. But at least you admit your mistakes, and you know deep inside that asking for TALIGN is wrong.

Thank you for your help Engkin, I do appreciate it.
My pleasure!

Kays

  • Hero Member
  • *****
  • Posts: 575
  • Whasup!?
    • KaiBurghardt.de
Re: question about bit field alignment in FPC records
« Reply #6 on: July 08, 2019, 11:54:38 pm »
[…] Consider using bitwise operators: AND, OR, XOR. […]
[…] You can achieve the same using shifting and logical operators. […]
Or use sets. Sets are awesome! Use sets if you wanna store flags. Sets. Sets. Sets. Sets. … Have I mentioned sets, yet?  8)
Yours Sincerely
Kai Burghardt

440bx

  • Hero Member
  • *****
  • Posts: 4037
Re: question about bit field alignment in FPC records
« Reply #7 on: July 09, 2019, 12:43:44 am »
and does not need cryptic ugly "C"ism alignment indicators. In fact, you don't need to use bitpacked at all, as Pascal provides alternatives.
yes, it does.  The problem is, the alternatives are less than they could be.

You are approaching this the wrong way. You should push to "Pascalize" Windows,
Good luck pushing to "Pascalize" Windows.

and even quit using Windows or any other OS that uses C for that matter.
What language is the OS you are currently using written in ?  Are you one of those that indulges in "do as I say, not as I do" ?

Ban/Boycott/Bar C (BBBC) from your life.
I wouldn't use the words "ban", "boycott" and/or "bar".  I'd say, seek something better which is the main reason I am here but, it seems there is little appetite to make Pascal better, more powerful and more capable among other things.   I'm starting to understand why C programmers don't migrate to Pascal.


Consider using bitwise operators: AND, OR, XOR. Probably "bitpacked" was added in a moment of weakness, just like +=, I say.
I think it's much better to consider simplifying data definitions and enhancing the compiler to make them possible.

Unsurprisingly, I disagree, again. The programmer should always be busy, always thinking, never lazy. It is a preventative precaution against Alzheimer at least. The effect of compilers taking burden of calculations on us mentally is bad. Similar to the effect of smartphones on our eyes. Just terrible.
I don't consider counting bits as a form of thinking.  I consider it tedious, boring and error prone.  I really doubt such activities prevent Alzheimers but, I'm no expert in that area, I might be wrong, though no evidence of any kind has surfaced to support that possibility.

But if you insist,
BBBC, simple!
very simple, also very unrealisitic unrealistic.


Consider it like separation between church and state, or between data and user interface.
There is nothing to separate.  It's only a data structure definition.  Pulverazing it into bits and pieces because a language doesn't support basic features is separation of thinking from action. 

Error is human nature, accept it.
I would say that's quite evident. 

Look at the full half of the cup: you know precisely how many bits there are in these gaps, because you had to recompile your code a few times to see if you counted them right this time. Plenty of pleasure when you finally do.
Your definition of pleasure is different than mine. But, if you derive pleasure from counting bits and getting it right, be my guest.



Wishful thinking is just bad. But at least you admit your mistakes, and you know deep inside that asking for TALIGN is wrong.
Apparently it is necessary to point out that I never claimed "wishful thinking" was good. Thank you for giving me credit for admitting my mistakes, after all your comments above, I'm feeling a bit surprised (pleasantly though.) 

Deep down inside, I think the compiler should provide a straightforward way of aligning bit fields.


My pleasure!
I'm pleased you derived some pleasure.  It wasn't a total loss.


You've shown being able to do a lot better than your previous post.
« Last Edit: July 09, 2019, 02:38:03 am by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: question about bit field alignment in FPC records
« Reply #8 on: July 09, 2019, 02:05:49 am »
The problem is, the alternatives are less than they could be.
By design. Any change creates a crack in the beauty of Pascal.

Good luck pushing to "Pascalize" Windows.
Working on it. I still need some more money, would you like to donate?

What language is the OS you are currently using written in ?  Are you one of those that indulges in "do as I say, not as I do" ?
Remember, I don't have a problem with bit field alignment. Plus, everyone knows: C is not safe, buggy, ugly, and unproductive.

I wouldn't use the words "ban", "boycott" and/or "bar".  I'd say, seek something better which is the main reason I am here but, it seems there is little appetite to make Pascal better, more powerful and more capable among other things.   I'm starting to understand why C programmers don't migrate to Pascal.

I think it's much better to consider simplifying data definitions and enhancing the compiler to make them possible.

I don't consider counting bits as a form of thinking.  I consider it tedious, boring and error prone.
If you insist, why should the compiler do the counting. It could be added to the IDE, instead. Make Pascal Great Again: MPGA.

very simple, also very unrealisitic.
Thaddy, 440bx just used the word unrealisitic.

There is nothing to separate.  It's only a data structure definition.  Pulverazing it into bits and pieces because a language doesn't support basic features is separation of thinking from action. 
Pulverizing it proves the language is strong. Only weak languages submit to the demands and needs of their users.

Deep down inside, I think the compiler should provide a straightforward way of aligning bit fields.
Now you start with aligning bit fields to bytes, next you would want to align to words, dwords..etc
This is a trap, a slippery way. What syntax do you suggest to achieve these variations?

440bx

  • Hero Member
  • *****
  • Posts: 4037
Re: question about bit field alignment in FPC records
« Reply #9 on: July 09, 2019, 02:36:22 am »
Thaddy, 440bx just used the word unrealisitic.
you managed to do something useful, you found a typo.  Thank you.   I am going to correct it.
« Last Edit: July 09, 2019, 02:51:58 am by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

jamie

  • Hero Member
  • *****
  • Posts: 6133
Re: question about bit field alignment in FPC records
« Reply #10 on: July 09, 2019, 03:09:14 am »
Code: Pascal  [Select][+][-]
  1. ype
  2.   TMyBitRecord = BitPacked Record
  3.      One:Record
  4.         F:0..1;
  5.         U:0..2;
  6.        End;
  7.      Two:Record
  8.         F:0..1;
  9.        End;
  10.   end;
  11.  
  12. begin
  13.   Writeln(SizeOf(TmyBitRecord));
  14.   Readln;
  15. end.                        
  16.  

I know you would love not to sub name it but,, This example prints 2 for the size.

I believe this is what you were looking for?

The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6133
Re: question about bit field alignment in FPC records
« Reply #11 on: July 09, 2019, 03:22:17 am »
don't feel so bad 440ex, I asked for anonymous records within a Record, I'll never see those.

That would solve the issue of not needing a sub-name added, just need to keep the inner names not as others.

 I also asked for a real UNION, same as the variant CASE so it can stay Pascal style but has a END to it so we
can place more types afterwards. Currently its cryptic to do this in Pascal, easy in C. Anonymous records
would also solve it if a real UNION wasn't offered so you wouldn't need to sub-name the fields..


« Last Edit: July 09, 2019, 03:25:02 am by jamie »
The only true wisdom is knowing you know nothing

440bx

  • Hero Member
  • *****
  • Posts: 4037
Re: question about bit field alignment in FPC records
« Reply #12 on: July 09, 2019, 03:48:39 am »
Code: Pascal  [Select][+][-]
  1. ype
  2.   TMyBitRecord = BitPacked Record
  3.      One:Record
  4.         F:0..1;
  5.         U:0..2;
  6.        End;
  7.      Two:Record
  8.         F:0..1;
  9.        End;
  10.   end;
  11.  
  12. begin
  13.   Writeln(SizeOf(TmyBitRecord));
  14.   Readln;
  15. end.                        
  16.  

I know you would love not to sub name it but,, This example prints 2 for the size.

I believe this is what you were looking for?
Yes, that is what I am looking for and, you are correct, I would really like not to have to define "extra boundaries" to get it done.

Thank you, I appreciate your help.

don't feel so bad 440ex, I asked for anonymous records within a Record, I'll never see those.
<snip>
I feel bad for the language.  Pascal has the potential to be _everything_ C is and then some in a nice well designed, well thought out language.

Its potential has been wasted for years now and, it doesn't  look like that is going to change.

It is what it is. 

Thank you again.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

jamie

  • Hero Member
  • *****
  • Posts: 6133
Re: question about bit field alignment in FPC records
« Reply #13 on: July 09, 2019, 03:54:21 am »
Here is a perfect example of anonymous records inside a record define...

Code: Pascal  [Select][+][-]
  1.  TMyBitRecord = BitPacked Record
  2.      Record   // Good case for nameless record;
  3.         one:0..1;
  4.         two:0..2;
  5.        End;
  6.       Record   // Good case for naemless reocord;
  7.        Case integer of
  8.         0:(X:Integer);
  9.         1:(Y:Integer);
  10.         End;
  11.       Record   //Good case for nameless recorc.
  12.         three:0..1;
  13.        End;
  14.   end;                    
  15.  
  16.  
You see the perfection there ? :)

All those inner fields exposed and you still get your alignment for the bits and variant record
in the middle of the road.. All with out needing a sub-name added...

I just wish they would add that...
The only true wisdom is knowing you know nothing

440bx

  • Hero Member
  • *****
  • Posts: 4037
Re: question about bit field alignment in FPC records
« Reply #14 on: July 09, 2019, 04:16:19 am »
I just wish they would add that...
Yes, that does look very nice and uncluttered.

One thing that is easy to notice, this isn't the place where wishes come true.  :D
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018