-3

Reading https://en.cppreference.com/w/c/language/bit_field, are the following conclusions correct?

  • Adjacent bit-fields have no padding in between (this seems to be differentin 6.7.2.1 of the C-standard).
  • The placement of a bit-field within the storage-unit is implementation-defined.
  • The position of the bits inside a bit-field is implementation-defined.

(For C++ see also: Characteristics of bit-Fields in C++.)

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
wimalopaan
  • 4,838
  • 1
  • 21
  • 39
  • From draft N1570: *implementation may allocate any addressable storage unit large enough to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified* – Support Ukraine Jan 30 '23 at 10:40
  • 2
    wimalopaan, This question is quite broad,. It is almost a request for every aspect about _bit-fields_. Perhaps something narrower? – chux - Reinstate Monica Jan 30 '23 at 10:41
  • @chux-ReinstateMonica: neither in the C standard nor in the C++ standard I find my above points one/three answered. – wimalopaan Jan 30 '23 at 10:42
  • 1
    @wimalopaan Seems to me that your point one is covered by the quote I posted above. – Support Ukraine Jan 30 '23 at 10:43
  • @wimalopaan And for point one you should also read about unnamed bit-fields – Support Ukraine Jan 30 '23 at 10:47
  • relevant https://stackoverflow.com/questions/42336257/what-does-straddle-in-a-bitwise-context-mean – 463035818_is_not_an_ai Jan 30 '23 at 10:49
  • 1
    actually I think all your points are covered by "The following properties of bit-fields are implementation-defined: [...] Everything about the actual allocation details of bit-fields within the class object" – 463035818_is_not_an_ai Jan 30 '23 at 10:50
  • Can I read that safely as: "adjacent bit-fields are always packed (no padding) only if they are in the same allocation unit"? – wimalopaan Jan 30 '23 at 11:01
  • And: "the bits of a bit-field are all packed if the are located in the same allocation unit"? – wimalopaan Jan 30 '23 at 11:02
  • 1
    @wimalopaan bit-fields - you __need__ to read your implementation docs as everything importent about them is _"implementation defined"_. If you want portable bit-fields, then don't use them. Instead use fix-width integer type(s) with your own masking and packing/unpacking. – Richard Critten Jan 30 '23 at 11:04
  • I linked to the C++ standard draft, Support quoted from the C standard. What do you refer to? I think at first you need to understand that C and C++ are two different languages, when going into details they have very different rules. The language thas is the overlap of C and C++ is a horrible language – 463035818_is_not_an_ai Jan 30 '23 at 11:06
  • @463035818_is_not_a_number It would be helpful to me, if you answer my question for C and for C++, if the differ in some respect to this particular defail. – wimalopaan Jan 30 '23 at 11:12
  • I dont know C, and I am not going to write an asnwer that goes beyond most simple syntax stuff. Tagging as C and C++ is requesting others to write two answers bascially. Or worse, if someone writes a C answer then future readers seeking a C++ answer will be disappointed. You can decide for one language. Then you can either do your own research to see what is different, or you can ask two separate questions. – 463035818_is_not_an_ai Jan 30 '23 at 11:46
  • The question is too broad since it asks about two languages at once. As usual, C and C++ are different here as well. `std::bitset` for example, or the fact that structs in C++ are just public classes. Asking this question just for C or just for C++ is fine. Or asking about the differences between C and C++ is fine too. But please, not all 3 questions at once. These are pretty intricate questions even when narrowed down like that. – Lundin Jan 30 '23 at 11:53
  • Perplexed why some people are so pedantic about requiring only one language tag for all occasions. Reasonableness should allow for certain questions, eg., when one is asking for a comparison between attributes of language `A` against those of language `B`, certainly allowing tags for `A` and `B` should not only be allowed, but required. – ryyker Jan 30 '23 at 14:03
  • @ryyker: https://stackoverflow.com/questions/75284152/characteristics-of-bit-fields-in-c – wimalopaan Jan 30 '23 at 14:19
  • @463035818_is_not_a_number, questions about similarities and differences between C and C++ are on topic here, and it is appropriate for such questions to be tagged with both languages. – John Bollinger Jan 30 '23 at 15:41
  • @JohnBollinger I didnt understand the question as being about differences, but rather OP expecting that there are no differences. If they question was "What is different in C and C++" of course I would not suggest to decide for one language. OPs way of clarifying was to make 2 questions, one for C one for C++ btw – 463035818_is_not_an_ai Jan 30 '23 at 15:47

1 Answers1

3

As a preliminary, there is no language "C/C++" such as is referenced by the question title. C and C++ are distinct languages sharing a common subset. In particular, C is not a subset of C++.

With regard to C, all the specifics the current language spec (C17 at this moment) provides about bitfield layout are in paragraphs 6.7.2.1/11-12.

are the following conclusions correct?

  • Adjacent bit-fields have no padding in between (this seems to be differentin 6.7.2.1 of the C-standard).

Bit fields are not laid out directly within a structure. The C implementation lays out "addressable storage units" for them within the structure, and lays out bitfields within those. The sizes and alignment requirements of the ASUs are unspecified.

The spec does say that if there is sufficient space in the ASU to which one bitfield is assigned, then an immediately-following bitfield is packed into adjacent bits of the same ASU. This means that there are not padding bits between those bitfields. However, if there is not sufficient space, then it is implementation-defined whether the immmediately-following bitfield spans two ASUs or whether all its bits are assigned to a separate one, leaving unused (padding) bits in the first. Additionally, a zero-width bitfield can be used to force the bitfield following it to be assigned to a new ASU, possibly requiring padding bits in a previous one.

Moreover, the spec has nothing to say about whether there are padding bytes between ASUs. ASUs are not required to be uniform in size or to have the same alignment requirements as each other, so it is plausible that padding bytes would sometimes be required between them even in an implementation that is not intentionally perverse in this regard.

  • The placement of a bit-field within the storage-unit is implementation-defined.

The spec explicitly says that the order of bitfields within an ASU is implementation defined. That's in the right-to-left vs left-to-right sense. "Order" is not exactly the same thing as "placement", but I guess that's what you mean.

  • The position of the bits inside a bit-field is implementation-defined.

Not really. This is a question of representation, not layout, and the relevant paragraphs of C17 are 6.2.6.1/3-4:

Values stored in unsigned bit-fields and objects of type unsigned char shall be represented using a pure binary notation.

[...] Values stored in bit-fields consist of m bits, where m is the size specified for the bit-field. The object representation is the set of m bits the bit-field comprises in the addressable storage unit holding it.

Footnote 49 clarifies the meaning of "pure binary notation" if you need that. All other details of bitfield representation are unspecified or undefined, not implementation-defined, which means that you cannot rely on them being documented.


Differences in C++ include, but are not necessarily limited to:

  • C++ officially sanctions more declared types for bit fields than does C.
  • C++ defines a mechanism for declaring bitfields that contain padding bits, but C does not.
  • Bitfield allocation and alignment are implementation defined in C++ (vs unspecified in C).

The relevant section of the C++ spec is [class-bit], 11.4.10 in the current draft spec.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157