0

I think this is best explained with an example:

    #include <iostream>

struct A
{
    int a;
};
struct B
{
    A a;
    int b;
};
struct C: A
{
    int c;
};

static inline std::ostream& operator<< (std::ostream& os, const A& a)
{ return os << a.a; }
static inline std::ostream& operator<< (std::ostream& os, const B& b)
{ return os << b.a << " " << b.b; }
static inline std::ostream& operator<< (std::ostream& os, const C& c)
{ return os << c.a << " " << c.c; }

static_assert(std::is_pod<B>::value, "B");
static_assert(std::is_pod<A>::value, "A");
static_assert(std::is_trivial<C>::value, "C");
//static_assert(std::is_pod<C>::value, "C");

int main()
{
    std::cout << "sizeof(A) " << sizeof(A) << std::endl;
    std::cout << "sizeof(B) " << sizeof(B) << std::endl;
    std::cout << "sizeof(C) " << sizeof(C) << std::endl;
    B b = B{14,42};
    std::cout << "b " << b << std::endl;
    C c; c.a=15; c.c=43;
    std::cout << "c " << c << std::endl;
    B* bp = &b;
    std::cout << "(C)b " << *(C*)(bp) << std::endl;
    C* cp = &c;
    std::cout << "(B)c " << *(B*)(cp) << std::endl;

    return 0;
}

Output:

sizeof(A) 4
sizeof(B) 8
sizeof(C) 8
b 14 42
c 15 43
(C)b 14 42
(B)c 15 43

Why does C not qualify as standard_layout. As I would expect it has the same memory layout as B. What could potentially differ?

cpplearner
  • 13,776
  • 2
  • 47
  • 72
Troels Blum
  • 823
  • 8
  • 17
  • 1
    Perhaps [this standard layout concept reference](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType) could help you? The part that `C` breaks is "has no base classes with non-static data members". Also note that the rules changed in C++14. – Some programmer dude Jun 27 '18 at 23:07
  • Possible duplicate of [Why is C++11's POD "standard layout" definition the way it is?](https://stackoverflow.com/questions/7160901/why-is-c11s-pod-standard-layout-definition-the-way-it-is), possibly... not sure if its the same problem – kmdreko Jun 27 '18 at 23:08
  • Your logic may hold in this case, but does not hold in general. https://godbolt.org/g/ZqCiiB –  Jun 27 '18 at 23:11
  • Also see [What are Aggregates and PODs and how/why are they special?](https://stackoverflow.com/a/7189821/1708801) – Shafik Yaghmour Jun 27 '18 at 23:15
  • @Someprogrammerdude The way I understand the standard layout reference `C` should be a POD-type in C++14, but it is not just tested with gcc-7 – Troels Blum Jun 28 '18 at 08:56
  • @hvd In my mind your example only adds to the strangeness, since both `C` and `D` are POD-types https://godbolt.org/g/S1ZJNQ – Troels Blum Jun 28 '18 at 08:58
  • 1
    @TroelsBlum That's my understanding as well. – Some programmer dude Jun 28 '18 at 09:00
  • So just to be clear: I know how to solve the "problem". It is not about that. I just think it is curious that `C` in my original example is not a POD-type. I see that it is not from the StandardLayoutType reference. But I still dont understand why it could not be? – Troels Blum Jun 28 '18 at 09:02
  • 1
    @TroelsBlum They are indeed both POD types in my example, but `C` is laid out as `A`, then `B`, whereas the layout of `D` is just `B` (since the base class is empty). In other words, in the general case, there are examples where a base class *must* be laid out differently from if it were the initial member. –  Jun 28 '18 at 09:05

0 Answers0