Skip to content

proposal: Go 2: bit and byte allocation in structures #29650

@viper10652

Description

@viper10652

Context:
In data communication protocols there often is a structure or a record where fields can be less than 8 bits or fields that can be multiple bits and have very specific offsets.

C and C++ have bitfields and struct types, but the standard does not guarantee the byte alignment. The compiler is free to stuff the record with additional bytes according to the processor data bus size. Enforcement of stuffing can be controlled via compiler options but is not portable.

The Ada programming language provides record data types where exact bit and byte offsets can be specified.

Proposal:

type PACKET record big-endian {
f1 byte offset 0
f2 bitfield offset 1 {
bf1 bits 3 offset 0 // referenced as f2.bf1
bf2 bits 1 offset 3 // bit offset refers to the n-power value, i.e. mask for bf2 is 2^3
bf3 bits 4 offset 4 // offset of bitfield refers to lsb, other bits can be inferred from bits value
}
f3 uint32 offset 2
f4 range 0x0001 .. 0x0100 offset 6
}

Considerations:
1)
allow specification of endianness, e.g. big-endian or little-endian

compiler should statically check for field overlaps

  1. compiler should give warnings when the definition leaves gaps between fields

we should consider variants in record definitions

E.g.
type PTYPE enum {P1 = 1, P2 = 4, P3 = 8}
type PACKET record {
ptype PTYPE offset 0
switch ptype {
case P1:
f1 byte offset 2
f2 byte offset 3

case P2:
f1 uint16 offset 2
}
}

  1. it should be possible to safely convert between types.
    E.g.
    var datastream []byte
    var err error
    var pp PACKET
    pp, err := datastream
    Conversion errors can be caused when raw values are out of range for the associated record field types
    In this case, variable pp is Nil and err specifies which field is out of bounds

This conversion should be a mapping, rather than a copy function.
i.e. after the mapping, the start address of pp is the same as the start address of array datastream

This is useful in encoding/decoding data streams to logical data without having to iterate over the record fields.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions