Bit field support in PB Structures.

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Bit field support in PB Structures.

Post by Thunder93 »

I wish PureBasic could support bit fields in PB Structures. This way a person doesn't have to unionize multiple fields, needing to read or write multiple times the same unionized fields just to access or update other specific information.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
Maitre_Kanter
User
User
Posts: 84
Joined: Mon Sep 06, 2010 3:05 pm

Re: Bit field support in PB Structures.

Post by Maitre_Kanter »

Hello everybody,

is it possible to implement this new feature : Bit Field in structure ?

Code: Select all

struct {
   unsigned char bit1 : 1;
   unsigned char bit2 : 1;
   unsigned char bit3 : 1;
   unsigned char bit4 : 1;
   unsigned char bits : 4;
} C_BIT_Fields_Example;
Thank you in advance,
Arnaud.
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

Re: Bit field support in PB Structures.

Post by Thorium »

I dont think it's that usefull to support bit fields that way.
The usual way to work with bit fields is to use logical functions like OR, AND, NOT and shift functions. To test for set bits, delete bits and set bits. Since the smallest addressable unit is a byte you need at least a byte in the structure anyway.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Bit field support in PB Structures.

Post by Thunder93 »

I believe there's advantages of supporting bitfields. Memory usage, essentially, at the very lowest possible level. Then of course readability, the two top reasons I saw people move heaven and earth on here to have.

I'm planning on making a software firewall with PureBasic. Making a strong & stateful packet filter interests me. Having a small-footprint, and not cluttered with unnecessary procedures just because PB doesn't support so-far, the bitfields in structures. Having the convenience that I think a programming language should have.


User_Russian whose superb programmer, .. not that I'm saying you aren't, but we both can agree that User_Russian is good. This person not that long ago also shown interest in this move. http://www.purebasic.fr/english/viewtop ... =3&t=58265
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
Maitre_Kanter
User
User
Posts: 84
Joined: Mon Sep 06, 2010 3:05 pm

Re: Bit field support in PB Structures.

Post by Maitre_Kanter »

Thunder93
+1
User_Russian
Addict
Addict
Posts: 1518
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Bit field support in PB Structures.

Post by User_Russian »

Thorium, why in that case need structure?
After all, you can substitute structure, like this one:

Code: Select all

Structure x
  x.a
  y.l
EndStructure

str.x
str\x = 10
str\y = 20
To work with memory and get the same result.

Code: Select all

*str = AllocateMemory(5)
If *str
  PokeA(*str, 10)
  PokeL(*str+1, 20)
  FreeMemory(*str)
EndIf
But the code becomes less comprehensible and easy to make a mistake.

Now imagine that the program consists of many thousands of rows and structure needed to add a field.

Code: Select all

Structure x
  x.a
  z.w
  y.l
EndStructure

str.x
str\x = 10
str\y = 20
In program need not be modified, because the compiler will recalculate the offset fields.

But in this code, you need to change the offset fields, which can lead to errors if you accidentally forget to do it.

Code: Select all

*str = AllocateMemory(7)
If *str
  PokeA(*str, 10)
  PokeL(*str+3, 20)
  FreeMemory(*str)
EndIf
All this is similar to the proposed you use logical operators OR, AND, NOT, etc.
A shift function in PB, the arithmetic and are not logic, which may also lead to errors.

I think the Fred understands this and will add bit fields in struture.
PMV
Enthusiast
Enthusiast
Posts: 727
Joined: Sat Feb 24, 2007 3:15 pm
Location: Germany

Re: Bit field support in PB Structures.

Post by PMV »

User_Russian wrote:

Code: Select all

*str = AllocateMemory(5)
If *str
  PokeA(*str, 10)
  PokeL(*str+1, 20)
  FreeMemory(*str)
EndIf
I would prefer this

Code: Select all

Structure x
  x.a
  ;z.w
  y.l
EndStructure
*str.x = AllocateMemory(SizeOf(x))
If *str
  *str\x = 10
  *str\y = 20
  FreeMemory(*str)
EndIf
And if you would use OffsetOf(x\y) in your example ... no
need for this +1 constant and any recalculation :)

But yes, for plain bit-arithmetic this would be useful.

MFG PMV
User_Russian
Addict
Addict
Posts: 1518
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Bit field support in PB Structures.

Post by User_Russian »

You misunderstood blotted writing.
Thorium, believes that the bit fields are not needed and can emulate using logic operations.
It all the same, what to write about what structures are not needed and they can emulate the working memory as in the examples in my previous post.
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Bit field support in PB Structures.

Post by idle »

I think it would be useful to add bitfield support but it's not really needed
This is the best I could come up with sticking to a stuctureunion like method

Code: Select all

Macro sb(offset,val)     ;set bit 
   offset | (val << #offset) 
EndMacro 

Macro tb(offset,val)     ;test bit 
   offset & (val << #offset) 
EndMacro   

Structure bit_fields 
   StructureUnion 
      bit1.a    ;1    0    index                    
      bit2.a    ;1    1                     
      bit3.a    ;1    2                  
      bit4.a    ;1    3               
      bits.a    ;4    4    
   EndStructureUnion   
EndStructure 

#bit1 = 0   ; make consts of index in bitfield named the same as union fields 
#bit2 = 1 
#bit3 = 2
#bit4 = 3
#bits = 4

Global bf.bit_fields 
   
bf\sb(bit1,1)     ;set bit field (offset, value)  
bf\sb(bit3,1)     
bf\sb(bits,3) 

Debug bf\tb(bit1,1)     ;test bitfield (offset,value) 
Debug bf\tb(bit3,1)
Debug bf\tb(bits,3)

Debug RSet(Bin(bf\bits,#PB_Byte),8,"0") 

Windows 11, Manjaro, Raspberry Pi OS
Image
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

Re: Bit field support in PB Structures.

Post by Thorium »

I think bit fields are very usefull. I just dont think they are that usefull as structure members. Especialy if you work with hundrets or thousands of bits. Just having a byte with 4 flag bits and a nibble is pretty easy to handle with shift OR and AND allready. What would be interessting would be support for big bit fields. Not as structure member but as a memory block you can perform bit operations on that are hard to do right now.

Some usefull new commands would be:
-count set bits in bit field
-find position of first bit set
-find position of first bit cleared
-copy or move a subset of the bit field
-perform logical operations that cross byte borders
-etc.
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Bit field support in PB Structures.

Post by idle »

Thorium wrote:I think bit fields are very usefull. I just dont think they are that usefull as structure members. Especialy if you work with hundrets or thousands of bits. Just having a byte with 4 flag bits and a nibble is pretty easy to handle with shift OR and AND allready. What would be interessting would be support for big bit fields. Not as structure member but as a memory block you can perform bit operations on that are hard to do right now.

Some usefull new commands would be:
-count set bits in bit field
-find position of first bit set
-find position of first bit cleared
-copy or move a subset of the bit field
-perform logical operations that cross byte borders
-etc.
but then you'd be wanting data structures to use them with
I can add these to my bitmodule if you like
http://www.purebasic.fr/english/viewtop ... 40&t=57409
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Bit field support in PB Structures.

Post by Thunder93 »

Thanks idle. Really smart. That would help often enough. :)
idle wrote:I think it would be useful to add bitfield support but it's not really needed
This is the best I could come up with sticking to a stuctureunion like method

Code: Select all

Macro sb(offset,val)     ;set bit 
   offset | (val << #offset) 
EndMacro 

Macro tb(offset,val)     ;test bit 
   offset & (val << #offset) 
EndMacro   

Structure bit_fields 
   StructureUnion 
      bit1.a    ;1    0    index                    
      bit2.a    ;1    1                     
      bit3.a    ;1    2                  
      bit4.a    ;1    3               
      bits.a    ;4    4    
   EndStructureUnion   
EndStructure 

#bit1 = 0   ; make consts of index in bitfield named the same as union fields 
#bit2 = 1 
#bit3 = 2
#bit4 = 3
#bits = 4

Global bf.bit_fields 
   
bf\sb(bit1,1)     ;set bit field (offset, value)  
bf\sb(bit3,1)     
bf\sb(bits,3) 

Debug bf\tb(bit1,1)     ;test bitfield (offset,value) 
Debug bf\tb(bit3,1)
Debug bf\tb(bits,3)

Debug RSet(Bin(bf\bits,#PB_Byte),8,"0") 

ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Bit field support in PB Structures.

Post by Thunder93 »

I'm not able to unset, or set field to 0

Code: Select all

bf\sb(bit1,1)
bf\sb(bit1,0)
still reads 1. :shock:

idle wrote:I think it would be useful to add bitfield support but it's not really needed
This is the best I could come up with sticking to a stuctureunion like method
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Bit field support in PB Structures.

Post by idle »

change the sb macro to use an xor and then you can toggle the values
and use the testbit macro to perform a check if you need to clear a value

Code: Select all

Macro sb(offset,val=1) 
  offset ! (val << #offset) 
EndMacro  

Macro tb(offset,val=1)     ;test bit 
   offset & (val << #offset) 
EndMacro   

Structure bit_fields 
   StructureUnion 
      bit1.a    ;1    0    index                    
      bit2.a    ;1    1                     
      bit3.a    ;1    2                  
      bit4.a    ;1    3               
      bits.a    ;4    4    
   EndStructureUnion   
EndStructure 

#bit1 = 0   ; make consts of index in bitfield named the same as union fields 
#bit2 = 1 
#bit3 = 2
#bit4 = 3
#bits = 4

Global bf.bit_fields 
   
bf\sb(bit1)     ;set bit field (offset, value)  
bf\sb(bit3)     
bf\sb(bits,3) 

If bf\tb(bit1)  ;if the bit is set 
  bf\sb(bit1)     ;clear bit 
EndIf   

Debug bf\tb(bit1,1)     ;test bitfield (offset,value) 
Debug bf\tb(bit3,1)
Debug bf\tb(bits,3)

If bf\tb(bits,3)
  bf\sb(bits,3) 
EndIf   

Debug RSet(Bin(bf\bits,#PB_Byte),8,"0") 


Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Bit field support in PB Structures.

Post by Thunder93 »

Hi idle. Firstly much appreciation. You always trying help others with their desires and problems. Always showing good quality solutions, codes.

Your suggestion to use XOR, unfortunately I have already giving thought to that. However, I don't fancy the extra step to check for the conditions before updating. In small projects is ideal though.

There's something else I've encountered. When I'm naming constants to match structure field names. Often the constants already exists internally. Changing the structure field names even to slightest is undesirable.


I don't know if there's a better way to unset and set. However, here's what I have..

Code: Select all

Macro SET_tcpSYN(hdr)
  hdr\SYN | (1 & 1) << 1
EndMacro

Macro UNSET_tcpSYN(hdr)
  hdr\SYN | (1 & 1) << 1 - 2
EndMacro

Macro GET_tcpSYN(hdr)
  (hdr\SYN >> 1) & 1
EndMacro
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
Post Reply