11

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.

4
  • 1
    This wont answer your question, but might be relevant: stackoverflow.com/questions/3319717/… Commented Nov 17, 2016 at 12:43
  • You can check it by sizeof() function. Also, as far as I know, the only difference between structs and classes are, default class variable will be private, default struct variable will be public. You should read here: [stackoverflow.com/a/7762179/1867076] Commented Nov 17, 2016 at 12:45
  • 2
    Classes, in C++, are identical to structs in almost every way. The only difference is default access specifier (for classes - private, for structs - public) Commented Nov 17, 2016 at 12:46
  • 1
    @Prometheus No, I can't check it with sizeof(). sizeof() doesn't work with bit fields (see the link that Roy T. posted) Commented Nov 17, 2016 at 14:03

3 Answers 3

10

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.

Sign up to request clarification or add additional context in comments.

3 Comments

except for the default access level and default type of inheritance, although it's not used here.
When you say that the two codes are the same, do you mean that the compiled codes are strictly identical or only that they do the same thing?
@DonaldDuck I would expect the exact same code to be generated. Both class and struct have to follow the same rules ignoring the access specifiers so the compiler should generate the same code.
2

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

Comments

0

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.)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.