Can someone remind me how the order of bitsets maps to the bytes/bits in memory? Specifically, I’m curious about the following:
- Do the bits go in “little-endian” or “big-endian” relative to the containing field.
- How to map C bitfields to Odin bitfields in an ABI-compatible way, because I know C spec is weird on this
I would really appreciate it if someone drew a graphic, visually showing how the bits go into the memory. Also noting that this post is likely to be found someone else looking at how bit_fields work
Endianness is determined by the backing integer.
Order of bits is 1<<bit_value.
bit_set or bit_field? The title says bit_field, the text says bitsets but also mentions C bitfields (closer to bit_field than bit_set).
For bit_set, the flags occupy bits from least significant to most significant. If no backing type is specified, then bit 0 (the least significant bit) corresponds to the minimum value of the enum/range of the bitset, and the bitset is as small as it can be to fit the range. If a backing type is specified, then bit 0 always corresponds to the 0 value. The operations are done using integers, and so should use the same endianness rules as the backing integer.
For bit_fields, the fields are laid out from the least-significant bits to the most-significant bits of the backing integer type type with no padding/alignment in between. Last I heard, the actual layout of bitfields in C isn’t actually specified and could vary from compiler to compiler, but I think they tend to do roughly the same (but you should definitely verify rather than just counting on it).
That being said, I don’t think bit_fields handle endian-specific integers as they should; see #4559. It seems like native endianness is always used.
BE :: bit_field u16be { lsb: byte | 8, msb: byte | 8 }
LE :: bit_field u16le { lsb: byte | 8, msb: byte | 8 }
// on a little-endian system
fmt.printfln("%x", transmute([2]byte)BE{ lsb=0x55, msb=0xaa }) // [55, aa], backwards?
fmt.printfln("%x", transmute([2]byte)LE{ lsb=0x55, msb=0xaa }) // [55, aa], makes sense
I apologize for the confusion. This is a question about bit_fields
I can wrap my head around whole bytes, but what about if we had u8-typed bitfield with two 4-bit integers. Would the first field correspond to the lowest 4-bits of the byte and the second the highest 4-bits of the byte?
As silly as this sounds but the easiest way to find out is to test yourself. It might help your intuition better. Even if @Barinzaya’s example was pretty good in my opinion.