This is a nice syntax, but the functionality seems essentially the same as bit fields in C. Does this provide anything additional?
Packed structs in Zig make bit/flag sets trivial
31–40 of 147 posts
Re: Packed structs in Zig make bit/flag sets trivial
#32One area where this is still less flexible than regular bit masking is that quite often I want to access groups of bits as a value. For instance if the bits represent in/out pins on a chip emulator, sometimes I want to access unique data bus pins, and sometimes I want to set or get the data bus value. Maybe Zig can handle this case with unions though, I haven't tried this yet (this would require that unions can work…
> this would require that unions can work on the 'bit level' in packed structs
Just as Zig has packed structs, it also has packed unions. So that part shouldn't be an issue.
Re: Packed structs in Zig make bit/flag sets trivial
#33So `unsigned flag:1`?
Re: Packed structs in Zig make bit/flag sets trivial
#34One area where this is still less flexible than regular bit masking is that quite often I want to access groups of bits as a value. For instance if the bits represent in/out pins on a chip emulator, sometimes I want to access unique data bus pins, and sometimes I want to set or get the data bus value. Maybe Zig can handle this case with unions though, I haven't tried this yet (this would require that unions can work…
One thing that is a bit noisy is that you have to specify the bit index when you name the individual bits, as in (from that article):
static let secondDay = ShippingOptions(rawValue: 1
Upside from that is that it makes it clear what bit each value specifies, and won’t easily accidentally change them when you reorder definitions, or insert or remove them. I can see why they made that choice.I also guess OptionSet could have been implemented in Swift in a third party library, whereas this Zig feature cannot.
I also think/guess neither language guarantees multiple bits would get read or written in one instruction. If your hardware needs that, you probably have to go down a level, or look at the disassembly of your code to check what your compiler did.
Re: Packed structs in Zig make bit/flag sets trivial
#35This is a nice syntax, but the functionality seems essentially the same as bit fields in C. Does this provide anything additional?
Bit fields in C are notoriously non-portable (exact physical layout depends on the compiler). Is Zig any better (apart from the fact that there is only one Zig compiler for now)?
Re: Packed structs in Zig make bit/flag sets trivial
#36Earlier quoted context omitted.
Far as I can tell 'don't use bit fields' is something students learn from their CS professors along with don't use goto, multiple returns, continue statements, pass structs by value, and always convert to big endian when sending data over a wire. My experience is C compilers have ways packing and defining the order of bitfields and structs.
>always convert to big endian when sending data over a wire What is this awful advice. Only convert to big-endian where legacy demands it.
Endianness is really perfectly named: a meaningless difference that generations of people fight holy wars over.
Re: Packed structs in Zig make bit/flag sets trivial
#37We can also do better in those other languages, too. For example, in Rust, I can use a crate like `bitfield` which gives me a macro with which I can write
bitfield! {
pub struct Color(u32);
red, set_red: 0;
green, set_green: 1;
blue, set_blue: 2;
alpha, set_alpha: 3;
}
Don't get me wrong: it's cool that functionality like this is built-in in Zig, since having to rely on third-party functionality for something like this is not always what you want. But Zig is not, as this article implies, uniquely capable of expressing this kind of thing.Re: Packed structs in Zig make bit/flag sets trivial
#38Earlier quoted context omitted.
I don't know why you haven't come across them but personally I've used bitfields a lot over my career as a video game programmer at different companies. You can have arbitrary bit width integers as well. It's not really very different to zig.
> You can have arbitrary bit width integers as well. This is news to me, how? AFAIK they'll only eventually make it into C23 with _BitInt(N). ...and apart from building a C++ wrapper class of course, but how would this pack with data outside the class - like the 4 + 28 bits example in the blog post. Also IIRC when I tinkered with C/C++ bitfields, some compilers (at least MSVC I think?) didn't properly pack the bits (…
[0] section "Notes" in https://en.cppreference.com/w/cpp/language/bit_field
Re: Packed structs in Zig make bit/flag sets trivial
#39> This all works, people have been doing it for years in C, C++, Java, Rust, and more. In Zig, we can do better. We can also do better in those other languages, too. For example, in Rust, I can use a crate like `bitfield` which gives me a macro with which I can write bitfield! { pub struct Color(u32); red, set_red: 0; green, set_green: 1; blue, set_blue: 2; alpha, set_alpha: 3; } Don't get me wrong: it's cool that fu…
Re: Packed structs in Zig make bit/flag sets trivial
#40 bitfield ColorWriteMaskFlags : u32 {
red 1 bool,
green 1 bool,
blue 1 bool,
alpha 1 bool,
};
The number after the field name is the bit size. An (offset, size) pair can be used instead (offsets start at 0 when not explicit). After that can be nothing (the bit field is an unsigned number), or the word 'bool' (the bit field is a boolean) or the word 'signed' (the bit field is a signed number in two's complement). The raw value of the bitfield can always be accessed with 'foo.#raw'.EDIT: There's also no restriction to how multiple fields can overlap, as long as they all fit within the backing type.