Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/bit field"

From cppreference.com
< cpp‎ | language
(link to integral constant expression)
m ({{spar optional}}, fmt.)
 
(28 intermediate revisions by 10 users not shown)
Line 1: Line 1:
{{title|Bit field}}
+
{{title|Bit-field}}
 
{{cpp/language/classes/navbar}}
 
{{cpp/language/classes/navbar}}
Declares a class data member with explicit size, in bits. Adjacent bit field members may be packed to share and straddle the individual bytes.
+
Declares a class data member with explicit size, in bits. Adjacent bit-field members may (or may not) be packed to share and straddle the individual bytes.
  
A bit field declaration is a {{rlp|data_members|class data member declaration}} which uses the following declarator:
+
A bit-field declaration is a {{rlp|data members|class data member declaration}} which uses the following declarator:
  
 
{{sdsc begin}}
 
{{sdsc begin}}
 
{{sdsc|num=1|1=
 
{{sdsc|num=1|1=
{{spar|identifier}}{{mark optional}} {{spar|attr}}{{mark optional}} {{ttb|:}} {{spar|size}}
+
{{spar optional|identifier}} {{spar optional|attr}} {{ttb|:}} {{spar|size}}
 
}}
 
}}
 
{{sdsc|num=2|notes={{mark since c++20}}|1=
 
{{sdsc|num=2|notes={{mark since c++20}}|1=
{{spar|identifier}}{{mark optional}} {{spar|attr}}{{mark optional}} {{ttb|:}} {{spar|size}} {{spar|brace-or-equal-initializer}}
+
{{spar optional|identifier}} {{spar optional|attr}} {{ttb|:}} {{spar|size}} {{spar|brace-or-equal-initializer}}
 
}}
 
}}
 
{{sdsc end}}
 
{{sdsc end}}
  
The ''type'' of the bit field is introduced by the {{spar|decl-specifier-seq}} of the {{rlp|declarations|declaration syntax}}.
+
The ''type'' of the bit-field is introduced by the {{spar|decl-specifier-seq}} of the {{rlp|declarations|declaration syntax}}.
  
 
{{par begin}}
 
{{par begin}}
{{par | {{spar|attr}}{{mark c++11}} | optional sequence of any number of [[cpp/language/attributes|attributes]]}}
+
{{par|{{spar|attr}}|{{mark since c++11}} sequence of any number of {{rlp|attributes}}}}
{{par | {{spar|identifier}} | the name of the bit field that is being declared. The name is optional: nameless bitfields introduce the specified number of bits of padding}}
+
{{par|{{spar|identifier}}|the name of the bit-field that is being declared. The name is optional: unnamed bit-fields introduce the specified number of {{rlp|object#Object representation and value representation|padding bits}}.}}
{{par | {{spar|size}} | an [[cpp/language/constant_expression#Integral_constant_expression|integral constant expression]] with a value greater or equal to zero. When greater than zero, this is the number of bits that this bit field will occupy. The value zero is only allowed for nameless bitfields and has special meaning: it specifies that the next bit field in the class definition will begin at an allocation unit's boundary.}}
+
{{par|{{spar|size}}|an {{rlp|constant expression#Integral constant expression|integral constant expression}} with a value greater or equal to zero. 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 [[#zero size|special meaning]].}}
{{par | {{spar| brace-or-equal-initializer}} | [[cpp/language/data_members#Member_initialization|default member initializer]] to be used with this bit field }}
+
{{par|{{spar|brace-or-equal-initializer}}|{{rlp|data members#Member initialization|default member initializer}} to be used with this bit-field}}
 
{{par end}}
 
{{par end}}
  
 
===Explanation===
 
===Explanation===
The number of bits in a bit field sets the limit to the range of values it can hold:
+
The type of a bit-field can only be integral or (possibly cv-qualified) enumeration type, an unnamed bit-field cannot be declared with a cv-qualified type.
  
{{example|code=#include <iostream>
+
A bit-field cannot be a {{rlp|static|static data member}}.
struct S {
+
 
// three-bit unsigned field,
+
There are no bit-field {{rlp|value category|prvalues}}: lvalue-to-rvalue conversion always produces an object of the underlying type of the bit-field.
// allowed values are 0...7
+
 
unsigned int b : 3;
+
The number of bits in a bit-field sets the limit to the range of values it can hold:
 +
 
 +
{{example|code=
 +
#include <iostream>
 +
 
 +
struct S
 +
{
 +
    // three-bit unsigned field, allowed values are 0...7
 +
    unsigned int b : 3;
 
};
 
};
 +
 
int main()
 
int main()
 
{
 
{
     S s = {7};
+
     S s = {6};
     ++s.b; // unsigned overflow (guaranteed wrap-around)
+
   
     std::cout << s.b << '\n'; // output: 0
+
     ++s.b; // store the value 7 in the bit-field
 +
     std::cout << s.b << '\n';
 +
   
 +
    ++s.b; // the value 8 does not fit in this bit-field
 +
    std::cout << s.b << '\n'; // formally implementation-defined, typically 0
 
}
 
}
 +
|p=true
 +
|output=
 +
7
 +
0
 
}}
 
}}
  
Multiple adjacent bit fields are usually packed together (although this behavior is implementation-defined):
+
Multiple adjacent bit-fields are usually packed together (although this behavior is implementation-defined):
  
{{example|code=#include <iostream>
+
{{example
struct S {
+
|code=
 +
#include <bit>
 +
#include <cstdint>
 +
#include <iostream>
 +
 
 +
struct S
 +
{
 
     // will usually occupy 2 bytes:
 
     // will usually occupy 2 bytes:
     // 3 bits: value of b1
+
     unsigned char b1 : 3; // 1st 3 bits (in 1st byte) are b1
     // 2 bits: unused
+
     unsigned char    : 2; // next 2 bits (in 1st byte) are blocked out as unused
     // 6 bits: value of b2
+
     unsigned char b2 : 6; // 6 bits for b2 - doesn't fit into the 1st byte => starts a 2nd
     // 2 bits: value of b3
+
     unsigned char b3 : 2; // 2 bits for b3 - next (and final) bits in the 2nd byte
    // 3 bits: unused
+
    unsigned char b1 : 3, : 2, b2 : 6, b3 : 2;
+
 
};
 
};
 +
 
int main()
 
int main()
 
{
 
{
 
     std::cout << sizeof(S) << '\n'; // usually prints 2
 
     std::cout << sizeof(S) << '\n'; // usually prints 2
 +
 +
    S s;
 +
    // set distinguishable field values
 +
    s.b1 = 0b111;
 +
    s.b2 = 0b101111;
 +
    s.b3 = 0b11;
 +
 +
    // show layout of fields in S
 +
    auto i = std::bit_cast<std::uint16_t>(s);
 +
    // usually prints 1110000011110111
 +
    // breakdown is:  \_/\/\_/\____/\/
 +
    //                b1 u a  b2  b3
 +
    // where "u" marks the unused :2 specified in the struct, and
 +
    // "a" marks compiler-added padding to byte-align the next field.
 +
    // Byte-alignment is happening because b2's type is declared unsigned char;
 +
    // if b2 were declared uint16_t there would be no "a", b2 would abut "u".
 +
    for (auto b = i; b; b >>= 1) // print LSB-first
 +
        std::cout << (b & 1);
 +
    std::cout << '\n';
 
}
 
}
 +
|p=true
 +
|output=
 +
2
 +
1110000011110111
 
}}
 
}}
  
The special unnamed bit field of size zero can be forced to break up padding. It specifies that the next bit field begins at the beginning of its allocation unit:
+
{{anchor|zero size}}
 +
The special unnamed bit-field of size zero can be forced to break up padding. It specifies that the next bit-field begins at the beginning of its allocation unit:
 +
{{example
 +
|code=
 +
#include <iostream>
  
{{example|code=#include <iostream>
+
struct S
struct S {
+
{
 
     // will usually occupy 2 bytes:
 
     // will usually occupy 2 bytes:
 
     // 3 bits: value of b1
 
     // 3 bits: value of b1
 
     // 5 bits: unused
 
     // 5 bits: unused
     // 6 bits: value of b2
+
     // 2 bits: value of b2
     // 2 bits: value of b3
+
     // 6 bits: unused
 
     unsigned char b1 : 3;
 
     unsigned char b1 : 3;
 
     unsigned char :0; // start a new byte
 
     unsigned char :0; // start a new byte
     unsigned char b2 : 6;
+
     unsigned char b2 : 2;
    unsigned char b3 : 2;
+
 
};
 
};
 +
 
int main()
 
int main()
 
{
 
{
 
     std::cout << sizeof(S) << '\n'; // usually prints 2
 
     std::cout << sizeof(S) << '\n'; // usually prints 2
 +
                                    // would usually print 1 if not for
 +
                                    // the padding break in line 11
 
}
 
}
 +
|p=true
 +
|output=
 +
2
 
}}
 
}}
  
If the specified size of the bit field is greater than the size of its type, the value is limited by the type: a {{c|std::uint8_t b : 1000;}} would still hold values between 0 and 255. the extra bits become unused padding.
+
If the specified size of the bit-field is greater than the size of its type, the value is limited by the type: a {{c|std::uint8_t b : 1000;}} would still hold values between 0 and 255. the extra bits are {{rlp|object#Object representation and value representation|padding bits}}.
  
Because bit fields do not necessarily begin at the beginning of a byte, address of a bit field cannot be taken. Pointers and non-const references to bit fields are not possible. When {{rlp|reference_initialization|initializing a const reference}} from a bit field, a temporary is created (its type is the type of the bit field), copy initialized with the value of the bit field, and the reference is bound to that temporary.
+
Because bit-fields do not necessarily begin at the beginning of a byte, address of a bit-field cannot be taken. Pointers and non-const references to bit-fields are not possible. When {{rlp|reference initialization|initializing a const reference}} from a bit-field, a temporary is created (its type is the type of the bit-field), copy initialized with the value of the bit-field, and the reference is bound to that temporary.
 
+
{{rrev multi
The type of a bit field can only be integral or enumeration type.
+
|rev1=
 
+
There are no {{rlp|data members#Member initialization|default member initializers}} for bit-fields: {{c|1=int b : 1 = 0;}} and {{c|int b : 1 {0}<!---->}} are ill-formed.
A bit field cannot be a {{rlp|static|static data member}}.
+
|since2=c++20|rev2={{anchor|Cpp20 Default member initializers for bit fields}}
 
+
In case of ambiguity between the size of the bit-field and the default member initializer, the longest sequence of tokens that forms a valid size is chosen:
There are no bit field {{rlp|value category|prvalues}}: lvalue-to-rvalue conversion always produces an object of the underlying type of the bit field.
+
 
+
{{rev begin}}
+
{{rev|until=c++20|There are no {{rlp|data_members#Member_initialization|default member initializers}} for bit fields: {{c|int b : 1 {{=}} 0;}} and {{c|int b : 1 {0} }} are ill-formed.}}
+
{{rev|since=c++20|
+
In case of ambiguity between the size of the bit field and the default member initializer, the longest sequence of tokens that forms a valid size is chosen:
+
 
{{source|1=
 
{{source|1=
  int a;
+
int a;
  const int b = 0;
+
const int b = 0;
  struct S {
+
 
 +
struct S
 +
{
 
     // simple cases
 
     // simple cases
     int x1 : 8 = 42;               // OK; "= 42" is brace-or-equal-initializer
+
     int x1 : 8 = 42;             // OK; "= 42" is brace-or-equal-initializer
     int x2 : 8 { 42 };             // OK; "{ 42 }" is brace-or-equal-initializer
+
     int x2 : 8 {42};             // OK; "{42}" is brace-or-equal-initializer
 +
   
 
     // ambiguities
 
     // ambiguities
     int y1 : true ? 8 : a = 42;   // OK; brace-or-equal-initializer is absent
+
     int y1 : true ? 8 : a = 42;   // OK; brace-or-equal-initializer is absent
     int y2 : true ? 8 : b = 42;   // error: cannot assign to const int
+
     int y2 : true ? 8 : b = 42;   // error: cannot assign to const int
     int y3 : (true ? 8 : b) = 42; // OK; "= 42" is brace-or-equal-initializer
+
     int y3 : (true ? 8 : b) = 42; // OK; "= 42" is brace-or-equal-initializer
     int z : 1 {{!!}} new int { 0 };   // OK; brace-or-equal-initializer is absent
+
     int z : 1 {{!!}} new int{0};     // OK; brace-or-equal-initializer is absent
  };
+
};
 
}}
 
}}
 
}}
 
}}
{{rev end}}
 
  
 
===Notes===
 
===Notes===
The following properties of bit fields are ''implementation-defined''
+
The following properties of bit-fields are ''implementation-defined'':
* The value that results from assigning or initializing a signed bit field with a value out of range, or from incrementing a signed bit field past its range.
+
* The value that results from assigning or initializing a signed bit-field with a value out of range, or from incrementing a signed bit-field past its range.
* Everything about the actual allocation details of bit fields within the class object
+
* Everything about the actual allocation details of bit-fields within the class object.
:* For example, on some platforms, bit fields don't straddle bytes, on others they do
+
:* For example, on some platforms, bit-fields don't straddle bytes, on others they do.
:* Also, on some platforms, bit fields are packed left-to-right, on others right-to-left
+
:* Also, on some platforms, bit-fields are packed left-to-right, on others right-to-left.
{{rev begin}}
+
{{rev|until=c++14|
+
* Whether {{c|char}}, {{c|short}}, {{c|int}}, {{c|long}}, and {{c|long long}} bit fields that aren't explicitly {{c|signed}} or {{c|unsigned}} are signed or unsigned.
+
:* For example, {{c|int b:3;}} may have the range of values {{c|0..7}} or {{c|-4..3}}.
+
}}
+
{{rev end}}
+
  
In the C programming language, the width of a bit field cannot exceed the width of the underlying type.
+
In the C programming language, the width of a bit-field cannot exceed the width of the underlying type, and whether {{c|int}} bit-fields that are not explicitly {{c|signed}} or {{c|unsigned}} are signed or unsigned is implementation-defined. For example, {{c|int b:3;}} may have the range of values {{c|0..7}} or {{c|-4..3}} in C, but only the latter choice is allowed in C++.
 +
 
 +
===Defect reports===
 +
{{dr list begin}}
 +
{{dr list item|wg=cwg|dr=324|std=C++98|before=it was unspecified whether the return value<br>of an assignment to a bit-field is a bit-field|after=added bit-field specifications for<br>operators which may return lvalues}}
 +
{{dr list item|wg=cwg|dr=739|std=C++98|before=signedness of bit-fields that are neither declared<br>{{c|signed}} nor {{c|unsigned}} were implementation-defined|after=consistent with underlying types}}
 +
{{dr list item|wg=cwg|dr=2229|std=C++98|before=unnamed bit-fields could be declared with a cv-qualified type|after=prohibited}}
 +
{{dr list item|wg=cwg|dr=2511|std=C++98|before=cv-qualifications were not allowed in bit-field types|after=bit-fields can have cv-qualified<br>enumeration types}}
 +
{{dr list end}}
  
 
===References===
 
===References===
 +
{{ref std c++23}}
 +
{{ref std|section=11.4.10|title=Bit-fields|id=class.bit}}
 +
{{ref std end}}
 +
{{ref std c++20}}
 +
{{ref std|section=11.4.9|title=Bit-fields|id=class.bit}}
 +
{{ref std end}}
 +
{{ref std c++17}}
 +
{{ref std|section=12.2.4|title=Bit-fields|id=class.bit}}
 +
{{ref std end}}
 +
{{ref std c++14}}
 +
{{ref std|section=9.6|title=Bit-fields|id=class.bit}}
 +
{{ref std end}}
 
{{ref std c++11}}
 
{{ref std c++11}}
{{ref std | section=9.6 | title=Bit-fields | id=class.bit}}
+
{{ref std|section=9.6|title=Bit-fields|id=class.bit}}
 +
{{ref std end}}
 +
{{ref std c++03}}
 +
{{ref std|section=9.6|title=Bit-fields|id=class.bit}}
 
{{ref std end}}
 
{{ref std end}}
 
{{ref std c++98}}
 
{{ref std c++98}}
{{ref std | section=9.6 | title=Bit-fields | id=class.bit}}
+
{{ref std|section=9.6|title=Bit-fields|id=class.bit}}
 
{{ref std end}}
 
{{ref std end}}
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc see c | c/language/bit field | Bit fields}}
+
{{dsc inc|cpp/utility/dsc bitset}}
{{dsc inc | cpp/utility/dsc bitset}}
+
{{dsc inc|cpp/container/dsc vector_bool}}
 +
{{dsc|[[cpp/numeric#Bit manipulation .28since C.2B.2B20.29|'''Bit manipulation''']] {{mark c++20}}|utilities to access, manipulate, and process individual bits and bit sequences}}
 +
{{dsc see c|c/language/bit field|Bit-fields|nomono=true}}
 
{{dsc end}}
 
{{dsc end}}
 +
 +
{{langlinks|es|ja|ru|zh}}

Latest revision as of 13:45, 2 October 2023

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Declares a class data member with explicit size, in bits. Adjacent bit-field members may (or may not) be packed to share and straddle the individual bytes.

A bit-field declaration is a class data member declaration which uses the following declarator:

identifier (optional) attr (optional) : size (1)
identifier (optional) attr (optional) : size brace-or-equal-initializer (2) (since C++20)

The type of the bit-field is introduced by the decl-specifier-seq of the declaration syntax.

attr - (since C++11) sequence of any number of attributes
identifier - the name of the bit-field that is being declared. The name is optional: unnamed bit-fields introduce the specified number of padding bits.
size - an integral constant expression with a value greater or equal to zero. 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.
brace-or-equal-initializer - default member initializer to be used with this bit-field

Contents

[edit] Explanation

The type of a bit-field can only be integral or (possibly cv-qualified) enumeration type, an unnamed bit-field cannot be declared with a cv-qualified type.

A bit-field cannot be a static data member.

There are no bit-field prvalues: lvalue-to-rvalue conversion always produces an object of the underlying type of the bit-field.

The number of bits in a bit-field sets the limit to the range of values it can hold:

#include <iostream>
 
struct S
{
    // three-bit unsigned field, allowed values are 0...7
    unsigned int b : 3;
};
 
int main()
{
    S s = {6};
 
    ++s.b; // store the value 7 in the bit-field
    std::cout << s.b << '\n';
 
    ++s.b; // the value 8 does not fit in this bit-field
    std::cout << s.b << '\n'; // formally implementation-defined, typically 0
}

Possible output:

7
0

Multiple adjacent bit-fields are usually packed together (although this behavior is implementation-defined):

#include <bit>
#include <cstdint>
#include <iostream>
 
struct S
{
    // will usually occupy 2 bytes:
    unsigned char b1 : 3; // 1st 3 bits (in 1st byte) are b1
    unsigned char    : 2; // next 2 bits (in 1st byte) are blocked out as unused
    unsigned char b2 : 6; // 6 bits for b2 - doesn't fit into the 1st byte => starts a 2nd
    unsigned char b3 : 2; // 2 bits for b3 - next (and final) bits in the 2nd byte
};
 
int main()
{
    std::cout << sizeof(S) << '\n'; // usually prints 2
 
    S s;
    // set distinguishable field values
    s.b1 = 0b111;
    s.b2 = 0b101111;
    s.b3 = 0b11;
 
    // show layout of fields in S
    auto i = std::bit_cast<std::uint16_t>(s);
    // usually prints 1110000011110111
    // breakdown is:  \_/\/\_/\____/\/
    //                 b1 u a   b2  b3
    // where "u" marks the unused :2 specified in the struct, and
    // "a" marks compiler-added padding to byte-align the next field.
    // Byte-alignment is happening because b2's type is declared unsigned char;
    // if b2 were declared uint16_t there would be no "a", b2 would abut "u".
    for (auto b = i; b; b >>= 1) // print LSB-first
        std::cout << (b & 1);
    std::cout << '\n';
}

Possible output:

2
1110000011110111

The special unnamed bit-field of size zero can be forced to break up padding. It specifies that the next bit-field begins at the beginning of its allocation unit:

#include <iostream>
 
struct S
{
    // will usually occupy 2 bytes:
    // 3 bits: value of b1
    // 5 bits: unused
    // 2 bits: value of b2
    // 6 bits: unused
    unsigned char b1 : 3;
    unsigned char :0; // start a new byte
    unsigned char b2 : 2;
};
 
int main()
{
    std::cout << sizeof(S) << '\n'; // usually prints 2
                                    // would usually print 1 if not for
                                    // the padding break in line 11
}

Possible output:

2

If the specified size of the bit-field is greater than the size of its type, the value is limited by the type: a std::uint8_t b : 1000; would still hold values between 0 and 255. the extra bits are padding bits.

Because bit-fields do not necessarily begin at the beginning of a byte, address of a bit-field cannot be taken. Pointers and non-const references to bit-fields are not possible. When initializing a const reference from a bit-field, a temporary is created (its type is the type of the bit-field), copy initialized with the value of the bit-field, and the reference is bound to that temporary.

There are no default member initializers for bit-fields: int b : 1 = 0; and int b : 1 {0} are ill-formed.

(until C++20)

In case of ambiguity between the size of the bit-field and the default member initializer, the longest sequence of tokens that forms a valid size is chosen:

int a;
const int b = 0;
 
struct S
{
    // simple cases
    int x1 : 8 = 42;              // OK; "= 42" is brace-or-equal-initializer
    int x2 : 8 {42};              // OK; "{42}" is brace-or-equal-initializer
 
    // ambiguities
    int y1 : true ? 8 : a = 42;   // OK; brace-or-equal-initializer is absent
    int y2 : true ? 8 : b = 42;   // error: cannot assign to const int
    int y3 : (true ? 8 : b) = 42; // OK; "= 42" is brace-or-equal-initializer
    int z : 1 || new int{0};      // OK; brace-or-equal-initializer is absent
};
(since C++20)

[edit] Notes

The following properties of bit-fields are implementation-defined:

  • The value that results from assigning or initializing a signed bit-field with a value out of range, or from incrementing a signed bit-field past its range.
  • Everything about the actual allocation details of bit-fields within the class object.
  • For example, on some platforms, bit-fields don't straddle bytes, on others they do.
  • Also, on some platforms, bit-fields are packed left-to-right, on others right-to-left.

In the C programming language, the width of a bit-field cannot exceed the width of the underlying type, and whether int bit-fields that are not explicitly signed or unsigned are signed or unsigned is implementation-defined. For example, int b:3; may have the range of values 0..7 or -4..3 in C, but only the latter choice is allowed in C++.

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
CWG 324 C++98 it was unspecified whether the return value
of an assignment to a bit-field is a bit-field
added bit-field specifications for
operators which may return lvalues
CWG 739 C++98 signedness of bit-fields that are neither declared
signed nor unsigned were implementation-defined
consistent with underlying types
CWG 2229 C++98 unnamed bit-fields could be declared with a cv-qualified type prohibited
CWG 2511 C++98 cv-qualifications were not allowed in bit-field types bit-fields can have cv-qualified
enumeration types

[edit] References

  • C++23 standard (ISO/IEC 14882:2024):
  • 11.4.10 Bit-fields [class.bit]
  • C++20 standard (ISO/IEC 14882:2020):
  • 11.4.9 Bit-fields [class.bit]
  • C++17 standard (ISO/IEC 14882:2017):
  • 12.2.4 Bit-fields [class.bit]
  • C++14 standard (ISO/IEC 14882:2014):
  • 9.6 Bit-fields [class.bit]
  • C++11 standard (ISO/IEC 14882:2011):
  • 9.6 Bit-fields [class.bit]
  • C++03 standard (ISO/IEC 14882:2003):
  • 9.6 Bit-fields [class.bit]
  • C++98 standard (ISO/IEC 14882:1998):
  • 9.6 Bit-fields [class.bit]

[edit] See also

implements constant length bit array
(class template) [edit]
space-efficient dynamic bitset
(class template specialization) [edit]
Bit manipulation (C++20) utilities to access, manipulate, and process individual bits and bit sequences
C documentation for Bit-fields