diff options
| author | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
| commit | 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch) | |
| tree | f1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/c/language%2Fbit_field.html | |
new repository
Diffstat (limited to 'devdocs/c/language%2Fbit_field.html')
| -rw-r--r-- | devdocs/c/language%2Fbit_field.html | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/devdocs/c/language%2Fbit_field.html b/devdocs/c/language%2Fbit_field.html new file mode 100644 index 00000000..016f0ca2 --- /dev/null +++ b/devdocs/c/language%2Fbit_field.html @@ -0,0 +1,102 @@ + <h1 id="firstHeading" class="firstHeading">Bit-fields</h1> <p>Declares a member with explicit width, in bits. Adjacent bit-field members may be packed to share and straddle the individual bytes.</p> +<p>A bit-field declaration is a <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> member declaration which uses the following <a href="declarations" title="c/language/declarations">declarator</a>:</p> +<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <span class="t-spar">identifier</span> <span class="t-mark">(optional)</span> <code>:</code> <span class="t-spar">width</span> </td> <td class="t-sdsc-nopad"> </td> <td class="t-sdsc-nopad"> </td> +</tr> +</table> <table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">identifier</span> </td> <td> - </td> <td> a name of the bit-field that is being declared. The name is optional: nameless bit-fields introduce the specified number of bits of padding </td> +</tr> <tr class="t-par"> <td> <span class="t-spar">width</span> </td> <td> - </td> <td> an integer <a href="constant_expression" title="c/language/constant expression">constant expression</a> with a value greater or equal to zero and less or equal the number of bits in the underlying type. When greater than zero, this is the number of bits that this bit-field will occupy. The value zero is only allowed for nameless bit-fields and has special meaning: it specifies that the next bit-field in the class definition will begin at an allocation unit's boundary. </td> +</tr> +</table> <h3 id="Explanation"> Explanation</h3> <p>Bit-fields can have only one of these <span class="t-rev-inl t-until-c99"><span>three</span><span><span class="t-mark-rev t-until-c99">(until C99)</span></span></span> – <span class="t-rev-inl t-since-c99 t-until-c23"><span>four</span><span><span class="t-mark-rev t-since-c99">(since C99)</span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span> types (possibly <a href="const" title="c/language/const">const</a> or <a href="volatile" title="c/language/volatile">volatile</a> qualified):</p> +<ul> +<li> <code>unsigned int</code>, for unsigned bit-fields (<code>unsigned int b:3;</code> has the range <code>0..7</code>) </li> +<li> <code>signed int</code>, for signed bit-fields (<code>signed int b:3;</code> has the range <code>-4..3</code>) </li> +<li> <code>int</code>, for bit-fields with implementation-defined signedness (Note that this differs from the meaning of the keyword <code>int</code> everywhere else, where it means "signed int"). For example, <code>int b:3;</code> may have the range of values <code>0..7</code> or <code>-4..3</code>. </li> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <ul><li> <code>_Bool</code>, for single-bit bit-fields (<code>bool x:1;</code>) has the range <code>0..1</code> and <a href="conversion" title="c/language/conversion">implicit conversions</a> to and from it follow the boolean conversion rules. </li></ul> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> <tr class="t-rev t-since-c23"> +<td> <ul><li> bit-precise integer types. (e.g. <code>_BitInt(5):4;</code> has the range <code>-8..7</code> and <code>unsigned _BitInt(5):4;</code> has the range <code>0..15</code>). </li></ul> </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <p>Additional implementation-defined types may be acceptable. <span class="t-rev-inl t-since-c11"><span>It is also implementation-defined whether a bit-field may have <a href="atomic" title="c/language/atomic">atomic</a> type.</span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span> The number of bits in a bit-field (<span class="t-spar">width</span>) sets the limit to the range of values it can hold:</p> +<div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h> + +struct S +{ + // three-bit unsigned field, + // allowed values are 0...7 + unsigned int b : 3; +}; + +int main(void) +{ + struct S s = {7}; + ++s.b; // unsigned overflow + printf("%d\n", s.b); // output: 0 +}</pre></div> </div> <p>Multiple adjacent bit-fields are permitted to be (and usually are) packed together:</p> +<div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h> + +struct S +{ + // will usually occupy 4 bytes: + // 5 bits: value of b1 + // 11 bits: unused + // 6 bits: value of b2 + // 2 bits: value of b3 + // 8 bits: unused + unsigned b1 : 5, : 11, b2 : 6, b3 : 2; +}; + +int main(void) +{ + printf("%zu\n",sizeof(struct S)); // usually prints 4 +}</pre></div> </div> <p>The special <i>unnamed bit-field</i> of <span class="t-spar">width</span> zero breaks up padding: it specifies that the next bit-field begins at the beginning of the next allocation unit:</p> +<div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h> + +struct S +{ + // will usually occupy 8 bytes: + // 5 bits: value of b1 + // 27 bits: unused + // 6 bits: value of b2 + // 15 bits: value of b3 + // 11 bits: unused + unsigned b1 : 5; + unsigned :0; // start a new unsigned int + unsigned b2 : 6; + unsigned b3 : 15; +}; + +int main(void) +{ + printf("%zu\n", sizeof(struct S)); // usually prints 8 +}</pre></div> </div> <p>Because bit-fields do not necessarily begin at the beginning of a byte, address of a bit-field cannot be taken. Pointers to bit-fields are not possible. Bit-fields cannot be used with <a href="sizeof" title="c/language/sizeof"><code>sizeof</code></a> <span class="t-rev-inl t-since-c11"><span>and <a href="_alignas" title="c/language/ Alignas"><code>_Alignas</code></a></span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span>.</p> +<h3 id="Notes"> Notes</h3> <p>The following usages of bit-fields causes <i>undefined behavior</i>:</p> +<ul><li> Calling <code><a href="../types/offsetof" title="c/types/offsetof">offsetof</a></code> on a bit-field </li></ul> <p>The following properties of bit-fields are <i>unspecified</i>:</p> +<ul><li> Alignment of the allocation unit that holds a bit-field </li></ul> <p>The following properties of bit-fields are <i>implementation-defined</i>:</p> +<ul> +<li> Whether bit-fields of type <code>int</code> are treated as signed or unsigned </li> +<li> Whether types other than <code>int</code>, <code>signed int</code>, <code>unsigned int</code><span class="t-rev-inl t-since-c99"><span>, <code>_Bool</code></span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span> <span class="t-rev-inl t-since-c23"><span>and (possibly <code>unsigned</code>) <code>_BitInt(N)</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> are permitted </li> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c11"> +<td> <ul><li> Whether atomic types are permitted </li></ul> </td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td> +</tr> </table> <ul> +<li> Whether a bit-field can straddle an allocation unit boundary </li> +<li> The order of bit-fields within an allocation unit (on some platforms, bit-fields are packed left-to-right, on others right-to-left) </li> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <p>Even though the number of bits in the object representation of <code>_Bool</code> is at least <code><a href="../types/limits" title="c/types/limits">CHAR_BIT</a></code>, the <span class="t-spar">width</span> of the bit-field of type <code>_Bool</code> cannot be greater than 1.</p> +</td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <p>In the C++ programming language, the width of a bit-field can exceed the width of the underlying type (but the extra bits are padding bits), and bit-fields of type <code>int</code> are always signed.</p> +<h3 id="References"> References</h3> <ul> +<li> C23 standard (ISO/IEC 9899:2023): </li> +<ul><li> 6.7.2.1 Structure and union specifiers </li></ul> +<li> C17 standard (ISO/IEC 9899:2018): </li> +<ul><li> 6.7.2.1 Structure and union specifiers </li></ul> +<li> C11 standard (ISO/IEC 9899:2011): </li> +<ul><li> 6.7.2.1 Structure and union specifiers </li></ul> +<li> C99 standard (ISO/IEC 9899:1999): </li> +<ul><li> 6.7.2.1 Structure and union specifiers </li></ul> +<li> C89/C90 standard (ISO/IEC 9899:1990): </li> +<ul><li> 3.5.2.1 Structure and union specifiers </li></ul> +</ul> <h3 id="See_also"> See also</h3> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/language/bit_field" title="cpp/language/bit field">C++ documentation</a></span> for <span class=""><span>Bit-field</span></span> </td> +</tr> </table> <div class="_attribution"> + <p class="_attribution-p"> + © cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br> + <a href="https://en.cppreference.com/w/c/language/bit_field" class="_attribution-link">https://en.cppreference.com/w/c/language/bit_field</a> + </p> +</div> |
