Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the C++ standard make any guarantee for the size of class types with no virtual member functions?

Tags:

c++

I use C++ for embedded programming.

Supposing I have to implement a strictly-defined (i.e. byte-by-byte) class type, can I add a constructor and some other non-virtual methods to it without objects of that type changing at the byte level? That is, can I assume that no additional data will be added to it?

I assume that RTTI is turned off.

I would like to be sure wheteher C++ standard defines this.

like image 948
ardabro Avatar asked Dec 13 '12 13:12

ardabro


2 Answers

Yes, if you only add constructors and/or non-virtual methods you will not change the size or the layout of the class, because the original class and the new class will be layout compatible (9.2 Class members [class.mem] #17), but only if they are standard-layout classes.

The standard-layout classes are defines as:

9 Classes [class]

A standard-layout class is a class that:

— has no non-static data members of type non-standard-layout class (or array of such types) or reference,

— has no virtual functions (10.3) and no virtual base classes (10.1),

— has the same access control (Clause 11) for all non-static data members,

— has no non-standard-layout base classes,

— either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and

— has no base classes of the same type as the first non-static data member.

like image 185
chill Avatar answered Sep 21 '22 23:09

chill


No, not really.

C++11 has this to say about sizeof:

[C++11: 5.3.5/2]: [..] When applied to a reference or a reference type, the result is the size of the referenced type. When applied to a class, the result is the number of bytes in an object of that class including any padding required for placing objects of that type in an array. The size of a most derived class shall be greater than zero (1.8). The result of applying sizeof to a base class subobject is the size of the base class type. When applied to an array, the result is the total number of bytes in the array. This implies that the size of an array of n elements is n times the size of an element.

... and that's about it. It doesn't specify what "required for placing objects of that type in an array" means, instead leaving that up to the target ABI.

The Itanium ABI, which has recently vanished from its previous home (grr) does make the sort of guarantees that you're looking for, if I recall correctly, but that is not the same as a C++ guarantee. Not the same at all.

You can use compiler-specific packing/alignment options to handle data members. But space increase due to virtual functions is beyond your control. You wouldn't expect any space to be added for non-virtual functions but this is not "guaranteed" either.

You can static_assert(sizeof T == x, "T needs to be x bytes wide") to detect whenever you broke some assumption with a code change. This is the best you're gonna get.

like image 23
Lightness Races in Orbit Avatar answered Sep 21 '22 23:09

Lightness Races in Orbit