Zero-sized subobjects. Why not?

This is the third question in a series of objects and subobjects of zero size. It is clear in the standards that member subobjects cannot have size zero, while base class subobjects can.

struct X {}; //empty class, complete objects of class X have nonzero size
struct Y:X { char c; }; //Y size may be 1 
struct Z {X x; char c;}; //Z size MUST be greater than 1

Why not allow JUST LIKE zero-dimensional object subobjects to zero dimensional subobjects?

TIA

EDIT after Conrad's answer: consider the following example:

struct X{}; 
struct D1:X{};
struct D2:D1, X {}; //D2 has 2 distinct subobjects of type X, can they both be 0 size and located at the same address?

If two subobjects of the base class of the same type X, as in my example, can be located at the same address, so they should be capable of member subobjects. If they cannot, the compiler specifically considers this case and therefore can consider the Konrad method (see the answer below) specifically and prohibit zero-sized subobjects if there are several of the same type in the same class. Where am I mistaken?

+5
source share
3 answers

- , , . . , , , .

@Konrad Rudolphs, -, , , , , , . , - . , "" () , . , , , .

, , .

, - , , . , , , , . , , ?

+1

-

() , :

struct X { virtual ~X() { /* Just so we can use typeid! */ } };
struct Y {
    X a;
    X b;
};

Y y;
// The standard requires that the following holds:
assert(typeid(y.a) != typeid(y.b) or &y.a != &y.b);

: ( ), .

+10

, - , " " , , , . , , , .

, , .

C

:

struct X{};
struct Y{};
struct Z {
   struct X x;
   struct Y y;
   int i;
};

Z POD ++ 03, C, x y . C POD. , C , POD ++ 03, :). , C . . , - .

, , , , y , x, - 5.10/2. , , .

IMO, .

, :

struct Z1 {
   struct X x[1];
   struct Y y[1];
   int i;
};

... , sizeof(Z1) == sizeof(Z) x y do (.. , ). .

,

, . , , " ", .. . , Stroustrup ++ - .

, , , typedefs ..; , , , , .

- Allocator STL - , , " ", .

... , . , . , , , .

There are many subtle things that do not work with this optimization. For example, you cannot memcpybits of a POD object of size zero into an array char, and then backward or between subobjects of size zero. I have seen people inject operator=using memcpy(I don’t know why ...) that would break such things. Presumably, this is less of a problem to break up such things for base classes instead of members.

+2
source

All Articles