Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #401191

Re: Storage needed when there are bit-field members

From Tim Rentsch <tr.17687@z991.linuxsc.com>
Newsgroups comp.lang.c
Subject Re: Storage needed when there are bit-field members
Date 2026-08-14 14:56 -0700
Organization A noiseless patient Spider
Message-ID <86o6f45pu7.fsf@linuxsc.com> (permalink)
References (7 earlier) <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>

Show all headers | View raw


Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>
>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>
>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>
> [...]
>
>>>> It would make a lot more sense *to me* if an N-bit bit field were
>>>> simply N bits.
>
> [...]
>
>>>                                                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".
>
> Perhaps you read more than I intended into my statement about N-bit
> bit-fields being "simply N bits".

It's possible, but I don't think I did.

> Thinking about this a bit more.
>
> As of C90, "A bit-field shall have a type that is a qualified or
> unqualified version of one of int, unsigned int, or signed int."
> The "shall" is outside a constraint, so an implementation could allow
> bit-fields of other types without triggering a required diagnostic,
> and many implementations did so.

Allowing other types is listed as a common extension.

> C99 added _Bool bit-fields, and explicitly allowed "some other
> implementation-defined type".  C23 allows bit-fields of bit-precise
> integer types;  I'll avoid thinking about that for now.
>
> Implementions commonly use the declared type of a bit-field to
> affect the layout, not necessarily of the bit-field itself, but
> of the containing structure.  Given that the standard doesn't
> require support for types other than bool and the int types (and
> now bit-precise integer types), the idea that `short bf:1` and
> `long bf:1` have different semantics is not, as far as I can tell,
> implied by anything in the standard.

They may have different semantics, depending on what particular
implementation-specific choices are made, but as best I can tell
the C standard doesn't require them to.

> I understand that implementations *can* allow other integer types
> in bit-field declarations, and that they can use the declared type
> in implementation-defined ways.

I don't think there is a specific explicit requirement that how a
bit-field's declared type affects layout be implementation-defined.
There is a general requirement that the number, order, and encodings
of bytes that make up an object be implementation-defined if they
are not explicitly specified.

> One possible approach would be to use the declared type only to
> determine the signedness of the bit-field (and its conversion
> behavior in the case of bool), and the upper bound for the number
> of bits (`int bf:33` is a constraint violation if int is 32 bits).
> In this relatively simple approach, there's no point in defining
> a bit-field with one of the char or short types.

I think that depends on how the allocatable storage unit for a
given bit-field is chosen.  The C standard is pretty vague about
what determines what allocatable storage unit is chosen in each
case, and under what circumstances that might vary from bit-field
to bit-field.

> Using gcc on Linux, if I define a 1-bit bit-field with a 64-bit type,
> that forces the containing structure to be at least 64 bits -- but
> not by reserving a 64-bit region to hold the bit-field.  If I define
> a struct containing a 1-bit unsigned long long bit-field followed by
> a 1-byte ordinary member, the second member is at a 1-bytes offset.
>
> 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 <stdio.h>
> #include <stddef.h>
> 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; };
>
>     printf("%-18s %-4s %-6s %s\n",
>            "type", "size", "offset", "struct-size");
>
>     printf("%-18s %-4zu %-6zu %-1zu\n",
>            "unsigned char",
>            sizeof (unsigned char),
>            offsetof(struct s1, c),
>            sizeof (struct s1));
>     printf("%-18s %-4zu %-6zu %-1zu\n",
>            "unsigned short",
>            sizeof (unsigned short),
>            offsetof(struct s2, c),
>            sizeof (struct s2));
>     printf("%-18s %-4zu %-6zu %-1zu\n",
>            "unsigned int",
>            sizeof (unsigned int),
>            offsetof(struct s3, c),
>            sizeof (struct s3));
>     printf("%-18s %-4zu %-6zu %-1zu\n",
>            "unsigned long",
>            sizeof (unsigned long),
>            offsetof(struct s4, c),
>            sizeof (struct s4));
>     printf("%-18s %-4zu %-6zu %-1zu\n",
>            "unsigned long long",
>            sizeof (unsigned long long),
>            offsetof(struct s5, c),
>            sizeof (struct s5));
> }
>
> and its output on my system (Ubuntu, x86_64):
>
> 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
>
> Again, the declared type of a bit-field doesn't affect how the
> bit-field itself is allocated, but it does affect the size of the
> containing struct, but it doesn't prevent other members from being
> allocated within that space.

You should be able to determine the layout exactly from the
implementation's documentation.  If you can't, that means the
implementation is not conforming, because these are implemenation
defined behaviors, and so much be documented.

Back to comp.lang.c | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Re: Microcontroller software stacks (was Re: this girl calls c ugly) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-06-21 14:13 -0700
  Re: Microcontroller software stacks (was Re: this girl calls c ugly) David Brown <david.brown@hesbynett.no> - 2026-06-22 08:58 +0200
    Re: Microcontroller software stacks (was Re: this girl calls c ugly) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-22 03:35 -0700
      Re: Microcontroller software stacks (was Re: this girl calls c ugly) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-06-22 10:50 +0000
      Re: Microcontroller software stacks (was Re: this girl calls c ugly) David Brown <david.brown@hesbynett.no> - 2026-06-22 12:59 +0200
      Storage needed when there are bit-field members Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-06-28 09:42 -0700
        Re: Storage needed when there are bit-field members Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-28 18:06 -0700
          Re: Storage needed when there are bit-field members Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-28 20:20 -0700
            Re: Storage needed when there are bit-field members Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-14 14:56 -0700
              Re: Storage needed when there are bit-field members scott@slp53.sl.home (Scott Lurndal) - 2026-08-14 22:30 +0000
                Re: Storage needed when there are bit-field members Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-15 16:10 -0700
                Re: Storage needed when there are bit-field members scott@slp53.sl.home (Scott Lurndal) - 2026-08-16 15:20 +0000
          Re: Storage needed when there are bit-field members Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-14 14:19 -0700
  Re: Microcontroller software stacks (was Re: this girl calls c ugly) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-06-22 10:45 +0000
    Re: Microcontroller software stacks (was Re: this girl calls c ugly) scott@slp53.sl.home (Scott Lurndal) - 2026-06-22 15:23 +0000
    Re: Microcontroller software stacks (was Re: this girl calls c ugly) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-14 13:23 -0700
      Re: Microcontroller software stacks (was Re: this girl calls c ugly) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-08-18 20:32 +0000
  Re: Microcontroller software stacks (was Re: this girl calls c ugly) scott@slp53.sl.home (Scott Lurndal) - 2026-06-22 15:04 +0000
    Re: Microcontroller software stacks (was Re: this girl calls c ugly) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-22 13:02 -0700
    Re: Microcontroller software stacks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-14 12:51 -0700
      Re: Microcontroller software stacks Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-15 05:02 +0800
        Re: Microcontroller software stacks bart <bc@freeuk.com> - 2026-08-15 01:18 +0100
          Re: Microcontroller software stacks Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-16 13:52 +0800
      Re: Microcontroller software stacks Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-14 14:06 -0700
      Re: Microcontroller software stacks scott@slp53.sl.home (Scott Lurndal) - 2026-08-14 21:42 +0000
        Re: Microcontroller software stacks Michael S <already5chosen@yahoo.com> - 2026-08-15 22:13 +0300
          Re: Microcontroller software stacks scott@slp53.sl.home (Scott Lurndal) - 2026-08-15 19:39 +0000
            Re: Microcontroller software stacks Michael S <already5chosen@yahoo.com> - 2026-08-15 23:22 +0300
              Re: Microcontroller software stacks scott@slp53.sl.home (Scott Lurndal) - 2026-08-16 14:38 +0000
                Re: Microcontroller software stacks Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-16 16:11 -0700
        Re: Microcontroller software stacks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-15 16:16 -0700
          Re: Microcontroller software stacks cross@spitfire.i.gajendra.net (Dan Cross) - 2026-08-18 20:34 +0000
        Re: Microcontroller software stacks Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-15 17:31 -0700

csiph-web