-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Rename packed struct to something more representative #12852
Comments
I would say there is no need at all to hold pointers in packed structs - for me they are just very convenient feature when dealing with various binary network protocols or binary file formats. |
I think |
@zzyxyzz const HasPadding = extern struct {
b: bool,
n: u32,
comptime {
std.debug.assert(@sizeOf(HasPadding) == 8);
}
};
const NoPadding = extern struct {
b: bool,
n: u32 align(1),
comptime {
std.debug.assert(@sizeOf(NoPadding) == 5);
}
}; |
@leecannon, thanks for the correction. |
tl;dr; I think both names show exact purpose and are fine. I am against changing them. extern struct - struct for usage in external modules/code/functions thus "extern". packed struct means bitpacked, which means it bitpacks integers. I think both names nail their task 100%. Andre Weissflog said on zig discord that he mistook packed struct with attribute((packed)) in C. But if we follow the zig philosophy then we shouldn't continue to carry this legacy into zig. Because we already have align(1). Packed means a different thing in zig and it's fine. |
That's exactly what this is about.
|
I don't understand the difference between extern and packed being a different level of readability defect because extern serves as much of a different purpose in Zig compared to C as packed. |
The whole argument is that somebody confuses packed with C packed and now suddenly we have to change it. But we're not C. We're a different language. |
I would argue that this issue goes deeper than naming and superficial differences between languages. I feel that bitpacking, while certainly a useful feauture, is the wrong default for dense, fixed-layout structures due to their limited composability: you cannot embed arrays or other non-packed structs, and you can have neither field pointers nor pointer fields. Byte-packed structs have none of these problems and should be the default packed layout unless you plan to do actual bit slicing. However, since the
The expectation that |
Yes, there are things to clarify. extern struct actually won't depend on C ABI if you don't use C types. This is kind of unwritten rule as of now. packed struct makes a compact memory representation and it doesn't guarantee memory layout. My proposal is to make clarify that extern can also be used for guarenteed memory layout, packed is NOT attribute((packed)), and for alignning to 1 you should do extern align(1). edit: |
I think before changing the name based on peoples' confusion, the documentation for
With such a skeletal and foreboding warning, I don't think it is any wonder people think EDIT: I will admit, I wouldn't be against this proposal if bitunion wasn't such a terrible name. The documentation needs to be fleshed out either way. |
How about just renaming |
bitfield and bitunion are horrible names. |
me too. |
btw, hello to middle endian byte order! :) |
related: #13009 |
|
How about:
|
Maybe we should just clarify what packing we need when using packed struct: // My byte packed struct So packed becomes sort of modifier to struct. |
i think |
One thing that really got me confused is that according to the documentation for extern struct:
But this seems to be false. There are use cases of extern structs which are not only for C ABI compability. For instance if I have a color struct:
and I want it to be so an array I don't really care about the naming that much, but would be nice if the documentation was more specific in this instance. |
Yes, this was basically my idea. I personally like the naming, just the docs need to be adjusted. |
I also think If
So putting something in a
The other side of the coin would favour attributes:
So, to get the equivalent of a The problems I can see with this solution are:
I personally would prefer first class types for this. I think // https://www.mouser.co.uk/datasheet/2/268/MCP7940N_Battery_Backed_I2C_RTCC_with_SRAM_2000501-2937048.pdf
// MCP7940N RTC with battery backup
const I2C_Command = bitfield {
address: u7,
write: bool,
}
const I2C_Packet = packet {
command: I2C_Command,
data: u8,
}
const MCP7940N_AlarmMask = enum u3 {
SECONDS = 0,
MINUTES = 1,
HOURS = 2,
DAY = 3,
DATE = 4,
RESERVED1 = 5,
RESERVED2 = 6,
ALL = 7,
}
// Could be a bitfield so padding would be implicit, but this is more explicit
const MCP7940N = packet {
sec: bitfield {
value: u7,
status: const bool,
},
min: bitfield {
value: u7,
const padding = 0,
},
hour: bitfield {
union {
bitfield {
value12: u4,
pm: bool,
},
value24: u5,
24hr: bool,
},
const padding = 0,
},
day: bitfield {
value: u3,
vbat: const bool,
pwrfail: const bool,
oscrun: const bool,
[2]const padding,
},
date: bitfield {
value: u6,
[2]const padding,
},
month: bitfield {
value: u5,
leap: bool,
[2]const padding,
},
year: bitfield {
value: u8,
},
}; I could have defined the default register values too, but this is just a quick demo. |
I think the criticism that C's packed and Zig's packed mean very different things is entirely valid. zig.org's front page suggests adding "a Zig compilation unit to C/C++ projects." It makes sense that we might acknowledge that features in C have names. Some things in C (like calling private things static, and having things be public by default) were, in Zig's opinion, mistakes. That's fair. I agree. However, the word "packed" for structs that don't have any padding seems pretty sensible to me. I'm not sure we should consume the valuable friction we're allotted by having it mean something entirely different. |
I think the core issue is not just that "packed" in Zig means something different to C.
Personally, when I want to control the memory layout of a struct, I reach for words like "layout", "padding", "packing" etc. I don't immediately think of "extern". Conversely, I think the code snippet by @BogdanTheGeek above was very easy to read. |
And the documentation makes things even more confusing by saying that:
Which simply isn't true, since you use |
I think we're all agreed that the documentation is misleading and confusing, but maybe it shouldn't be. Maybe Whether the name for that is Personally, I think |
I also hit this confusion when trying to understand the expected behavior of |
I agree with this, there should be a clear distinction between bitpacked and bytepacked. |
As Zig is a lot about communication, we should probably rename
packed struct
into something that represents more what it actually is.Right now, a lot of people assume that
packed struct
follows similar rules as regular orextern
structs, which isn't true anymore with stage2. Thus, a lot of confusion is created and people misusepacked structs
accidently or try to solve problems with them whereextern struct
is the right hammer.I propose to change the name of
packed struct
into something that clearly represents what it is. My current best guess would bebitrecord
orbitfield
, and respectivly renamepacked union
tobitunion
(which is not a good name).This change is also a good idea as you cannot put arrays or pointers into
packed struct
sThe text was updated successfully, but these errors were encountered: