简体   繁体   中英

Can bit fields be used in C++ classes?

In C structs, it is possible to specify another bit length than the default bit length of the type like this:

struct MyStruct{
    int myVar : 1;    //Size of myVar is 1 bit (so it can take values 0 or 1
    int myOtherVar: 4;    //Size of myOtherVar is 4 bits (so it can take values 0 to 15)
}

This is called bit fields.

My question is if it is also possible to do this in C++ classes, like this:

class MyClass{
    public:
        //Some methods
    private:
        int m_myAttribute : 1;
        int m_myOtherAttribute : 4;
}

I searched the web for this but all the examples I found of bit fields used structs, not classes.

I tested this code and it compiled just fine, but I would like to know if the size of the attributes are really the specified size or if the compiler just ignored the bit fields and used the standard int size.

Yes a class can have bit-field members. In C++ there is no difference between a class and a struct except for the default access level and the default inheritance type. They are both called class types. If you can do something in a struct then you can do that same thing in a class . Since the default access levels are different they will look a little different but you get the same thing. For instance

struct foo
{
    int m_myAttribute : 1;
    int m_myOtherAttribute : 4;
    int m_myOtherOtherAttribute : 27;
};

is the same as

class bar
{
public:
    int m_myAttribute : 1;
    int m_myOtherAttribute : 4;
    int m_myOtherOtherAttribute : 27;
};

Do note though that we had to use public: in the class since by default the members are private.

Now about the size of the bit fields in C++. [class.bit]/1 has all of the information you need on that:

The constant-expression shall be an integral constant expression with a value greater than or equal to zero. The value of the integral constant expression may be larger than the number of bits in the object representation (3.9) of the bit-field's type; in such cases the extra bits are used as padding bits and do not participate in the value representation (3.9) of the bit-field. Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [ Note: Bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others. —end note ]

emphasis mine

From this we get that the size of the bit-feild will be at least the size of the underlying data type but if you over allocate space then that extra space is turned into padding and is not used for the value of the bit-field member.

It is perfectly legal in C++ to use bit-fields with classes or structs. I also recommend this question to dive further into the similarities and differences of the two: What are the differences between struct and class in C++?

And yes the bit-size is really taken into account, just remember that the size of the memory layout is implementation-dependent

class test {
  int a : 3;
  void fun() {
      // std::cout << sizeof(a); // Illegal (*)
      a = 5; // Warning! Implicit truncation from int to 3-bit bitfield yields -3 (2's complement)
  }
};

int main() {
  std::cout << sizeof(test); // ABI-dependent, might be 4 bytes
}

(*) Let me also address your comment regarding the use of sizeof and bit-fields: it is not allowed to use sizeof on a glvalue designating a bit-field as in [expr.sizeof]/p1

As a matter of quality of implementation (QoI), yes the size of the members are really the specified size with all the compilers I know of.

If you are asking if the sizes MUST match (according to the standard), you have to ask yourself how you would tell? (In a standard conforming way.) If you can't (and I don't think you can), then under the as-if rule, the compiler can do what it likes.

For more details, see section 9.6 of the C++14 standard (actually n4296.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM