Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does inheritence force inflation of otherwise zero sized structs?

Tags:

c++

struct

Why does a zero-sized array force a struct to be zero sized when an otherwise empty struct has a size of 1, and why does inheriting from a non-zero-sized struct cause the struct to be inflated to the size of the base type?

Compiling via GCC 5.3.0, in case any answer depends on the c++ spec.

#include <iostream>

struct a {};
struct b { int x[0]; };
struct c : a{ int x[0]; };
struct d : b{ int x[0]; };

int main()
{
    std::cout << sizeof(a) << std::endl; // 1
    std::cout << sizeof(b) << std::endl; // 0
    std::cout << sizeof(c) << std::endl; // 4
    std::cout << sizeof(d) << std::endl; // 0
} 
like image 742
Tyler Stoney Avatar asked Apr 21 '21 20:04

Tyler Stoney


1 Answers

The ISO C++ standard does not recognize the possibility of a "zero-sized array". That should give you a compile error on a strictly-conforming implementation. While yes, there are a lot of permissive implementations that allow it, their behavior is not governed by the C++ standard.

Similarly, the ISO C++ standard does not permit any type T for which sizeof(T) is zero. Ever. Again, some implementation may do this, but it is not conforming with the standard.

So why it happens depends on the compiler and the expectations of the writer of that code. Zero-sized arrays are generally a C-ism (though C forbids them too, but the C-ism may predate C89), so while it might be meaningful in C code, how they interact with C++ features is really up to the compiler.

The reason c might have a size while d does not could be because a is a normal C++ struct that follows the C++ standard and b isn't. So c::a (the base class of c) still has to follow the normal rules of C++ to some degree, while d::b is completely up to whatever the compiler wants to make of it.

like image 176
Nicol Bolas Avatar answered Oct 23 '22 17:10

Nicol Bolas