Go: Beat Pods and Bit Packing

C-bit fields provide a rather convenient method for determining fields of arbitrary width in the structure (do not pay attention to portability problems for a minute.) For example, here is a simple structure with a couple of fields and a β€œflag”:

#pragma pack(push,1) struct my_chunk{ unsigned short fieldA: 16; unsigned short fieldB: 15; unsigned short fieldC: 1; }; #pragma pop() 

Adding #pragma operators packs this structure into a 32-bit word (providing alignment of manipulations with my_chunk pointer pointers, for example, together with saving space).

Access to each field is syntactically very good:

 struct my_chunk aChunk; aChunk.fieldA = 3; aChunk.fieldB = 2; aChunk.fieldC = 1; 

An alternative way to do this without the help of language is pretty ugly and pretty much turns into assembler. for example, One solution is to have bit shift macros for each field that you want to access:

 #define FIELD_A 0xFF00 #define FIELD_B 0x00FE #define FIELD_C 0x0001 #define get_field(p, f) ((*p)&f) #define set_field(p, f, v) (*p) = (v<<f) + (*p)&(~f) ... set_field(&my_chunk, FIELD_A, 12345); 

.. or something like that (for more formality, take a look at this one )

So the question is, if I want to β€œdo” bit fields in go, what is the best way to do this?

+8
source share
2 answers

Go has no current plans for struct bit fields.

You can write a Go package to do this; no assembler required.

+10
source

If the goal is to have a very small structure, you probably just do:

 package main import "fmt" type my_chunk uint32 func (c my_chunk) A() uint16 { return uint16((c & 0xffff0000) >> 16) } func (c *my_chunk) SetA(a uint16) { v := uint32(*c) *c = my_chunk((v & 0xffff) | (uint32(a) << 16)) } func main() { x := my_chunk(123) x.SetA(12) fmt.Println(xA()) } 

With the current 6g / 8g, you are looking at a function call with ~ 6 instructions for the receiver, and over time, such calls are likely to be nested.

+8
source

Source: https://habr.com/ru/post/886715/


All Articles