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: Sat, 15 Aug 2026 16:10:30 -0700 Organization: A noiseless patient Spider Lines: 79 Message-ID: <86cxvj3rq1.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> <111soae$1eq8$1@kst.eternal-september.org> <86o6f45pu7.fsf@linuxsc.com> <5GMfS.13614$EDc8.5150@fx24.iad> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Sat, 15 Aug 2026 23:10:32 +0000 (UTC) Injection-Info: dont-email.me; logging-data="3954883"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19pdcCDy4CTZg3ik4ByqY7PKJs+oNqfLeM="; posting-host="f88cfb7384c39afe54609bf3101f3803" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:vUHm+cNmUsh82OuMstNoqpzm9rE= sha1:3Rb4TZnsjQxKTqL4eP2UXUxT47g= sha256:USwau51wCYHhnzlC0w9IE3RAbqFbgMQTF+kv9Cijjog= sha1:WoCZRnKvhlDZNH+rV5C6CyIm1QU= sha256:c9levN+2lu6Felh9E1P/9mX9g0R8564pmkymqwH7DGg= Xref: csiph.com comp.lang.c:401223 scott@slp53.sl.home (Scott Lurndal) writes: > Tim Rentsch writes: > >> Keith Thompson writes: >> >>> Keith Thompson writes: >>> >>>> Tim Rentsch writes: >>>> >>>>> Keith Thompson writes: >>> >>> [...] >>> >>>>>> It would make a lot more sense *to me* if an N-bit bit field were >>>>>> simply N bits. >>> >>> [...] > > > >>> I had gotten the impression that the behavior is imposed by ABIs, >>> but my copy of the "System V Application Binary Interface AMD64 >>> Architecture Processor Supplement" just says: >>> >>> - bit-fields are allocated from right to left >> >> I think that means they are allocated in order of low-to-high, >> because the AMD64 architecture is little-endian. >> >>> - bit-fields must be contained in a storage unit appropriate for >>> its declared type >>> - bit-fields may share a storage unit with other struct / union >>> members >>> >>> which doesn't seem to be enough to specify the behavior I see >>> (and I find it annoyingly vague). >>> >>> Is there a document (ABI, compiler document, whatever) that specifies >>> the (odd, to me) behavior I'm seeing? >> >> As best I can tell the layout you are seeing is consistent with >> the rules stated above. Perhaps the rules are deliberately meant >> to be an under-specification (which IMO is not a bad thing). >> >>> Here's a test program: >>> >>> #include >>> #include >>> int main(void) { >>> struct s1 { unsigned char bf:1; unsigned char c; }; >>> struct s2 { unsigned short bf:1; unsigned char c; }; >>> struct s3 { unsigned int bf:1; unsigned char c; }; >>> struct s4 { unsigned long bf:1; unsigned char c; }; >>> struct s5 { unsigned long long bf:1; unsigned char c; }; > > FWIW, adding GCC's __attribute__((packed)) to each of those, we see: > >> type size offset struct-size >> unsigned char 1 1 2 >> unsigned short 2 1 2 >> unsigned int 4 1 4 >> unsigned long 8 1 8 >> unsigned long long 8 1 8 > > type size offset struct-size > unsigned char 1 1 2 > unsigned short 2 1 2 > unsigned int 4 1 2 > unsigned long 8 1 2 > unsigned long long 8 1 2 > > Which doesn't seem to violate the ABI rules you quoted. That's good to know I guess, although I'm not sure what it tells me. My impression is that using attribute__((packed)) produces code that may be less portable than not using it. Generally I try to write code that avoids compiler-specific constructs whenever feasible.