Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: Storage needed when there are bit-field members Date: Fri, 14 Aug 2026 14:19:32 -0700 Organization: A noiseless patient Spider Lines: 123 Message-ID: <86se4g5riz.fsf@linuxsc.com> References: <10v7b32$2u85v$1@dont-email.me> <10vjsg2$259m3$3@dont-email.me> <10vkk65$l8v$1@reader1.panix.com> <10vlvie$2ne3j$2@dont-email.me> <10vmh2e$b44$1@reader1.panix.com> <86h5mv8umk.fsf@linuxsc.com> <111amdq$1at39$1@dont-email.me> <111b35d$1duuq$1@kst.eternal-september.org> <86v7b27h20.fsf_-_@linuxsc.com> <111sgeq$3vq40$1@kst.eternal-september.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Fri, 14 Aug 2026 21:19:35 +0000 (UTC) Injection-Info: dont-email.me; logging-data="2956047"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+6l+F18mbS9CTRnZfc8mKkRDIDaP6zwMo="; posting-host="34d543ba31754db8d869ebd4dc5daf69" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:TMl/mwPY6zWXsWRh7wsCrirT7S8= sha1:b40JI2Pe1QsqbfpbI4ZXY/9frWw= sha256:2xQglWMCBMAl+RqeBQjq/5DFhDotVF5tvI/t8UjaxYU= sha1:7WzwASaeiB/z3woQh6zE6VDZIIU= sha256:P3Ht/6FItvXx2tZ0uNgqd+raXjNMJFM+hz6pjvFkpWI= Xref: csiph.com comp.lang.c:401188 Keith Thompson writes: > Tim Rentsch writes: > >> Keith Thompson writes: > > [...] > >>> But >>> uint32_t bf : 1; >>> is meaningfully different from >>> unsigned bf : 1; >>> >>> only because in most implementations (and ABIs), the underlying type >>> of a bit field affects the layout of the entire structure. > > [...] > >>> I accept that this is the case, but it's never made any sense to me, >>> and there's no hint of it in the C standard. >> >> I think saying there is not even a hint is an overstatement. The C >> standard says that an implementation "may allocate any addressable >> storage unit large enough to hold a bit-field." It shouldn't be a >> surprise that how much storage is allocated depends on the type of >> the bit-field member. For example, a bit-field of type 'unsigned' >> might very well choose a larger storage unit than what is chosen >> for a bit-field of type '_Bool'. It seems obvious that the type of >> a bit-field might affect what size and layout is chosen. > > I'm sure it seems obvious to you. As I said, it's not at all > obvious to me. > > Prior to C99, C didn't even require compilers to support bit-field > types other than int, unsigned int, and signed int. True, but allowing other types was listed as a common extension. > The declared > type might typically be used only to determine the signedness of the > bit-field (though I *think* most compilers permitted other types). > > Implementations are certainly not *required* to use the declared > type of a bit-field as a factor in deciding how to allocate it, > or how to allocate the rest of the structure. Allocating just one > byte for an isolated 1-bit bit-field of any declared type would > be conforming. A conforming compiler could use the declared type > only to determine the signedness and the maximum allowed width of > a bit-field (and its conversion behavior in the case of bool) Yes, it could. >>> For example, if I write: >>> uint64_t bf : 1; >>> >>> then the containing struct is typically at least 64 bits, even >>> though those other 63 bits aren't part of the bit field and other >>> members can be allocated within them. >>> >>> It would make a lot more sense *to me* if an N-bit bit field were >>> simply N bits. >> >> Two problems with that. One, it seems to be in conflict with what >> the C standard says about 0-width bit-fields. > > 0-width bit-fields are obviously a special case. Sorry for not making my point more clear. My comment is meant to to raise the question of whether struct x { _Bool foo:1; _Bool :0; char c; }; and struct y { unsigned foo:1; _Bool :0; char c; }; should be different. I'm inclined to think they should be, by which I mean my preference is for compilers where they would be. >> Two, the C standard >> explicitly allows allocating bit-fields using a high-to-low order >> or a low-to-high order (implementation-defined choice). Presumably >> this freedom is given to accommodate both big- and little-endian >> platforms. The idea that an N-bit bit-field should simply be N >> bits doesn't work in big-endian environments. It seems better to >> allow little-endian implementations to choose a size that matches >> what a big-endian implementation would use, rather than insisting >> that they be different. > > I honestly don't understand your point here. How does making > N-bit bit-fields N bits not work in a big-endian environment? > Can you elaborate? Of course endianness can affect how bit-fields > are allocated within a "storage unit". Suppose we have a little endian machine where bit-fields are allocated in a high-to-low order. Further suppose that unsigned ints are 32 bits. In such an environment, I would expect (or prefer) a definition like this struct foo { unsigned x:15; }; to be represented like so -------- -------- -XXXXXXX XXXXXXXX where the X's indicate where the bit-field goes, and the -'s indicate where there are padding bits. In such an environment, I would find it counterintuitive if this type were represented thus -XXXXXXX XXXXXXXX rather than as shown in the previous layout.