Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

empty base class optimization

Below is a simple test on ebco, I compiled it on both vc9 and g++. The outputs differ on both compilers. What I want to know is that whether the behavior of vc is conformant.

#include <iostream>

class empty
{
};

class empty_one : public empty {};
class empty_two : public empty {};

class non_empty
    : public empty_one
    , public empty_two
{
};

int main()
{
    std::cout << "sizeof(empty): " << sizeof(empty) << std::endl;
    std::cout << "sizeof(empty_one): " << sizeof(empty_one) << std::endl;
    std::cout << "sizeof(empty_two): " << sizeof(empty_two) << std::endl;
    std::cout << "sizeof(non_empty): " << sizeof(non_empty) << std::endl;

    std::cout << std::endl;

    non_empty a[2];

    void* pe10 = static_cast<empty*>(static_cast<empty_one*>(&a[0]));
    void* pe20 = static_cast<empty*>(static_cast<empty_two*>(&a[0]));
    std::cout << "address of non_empty[0]: " << &a[0] << std::endl;
    std::cout << "address of empty of empty_one: " << pe10 << std::endl;
    std::cout << "address of empty of empty_two: " << pe20 << std::endl;

    std::cout << std::endl;

    void* pe11 = static_cast<empty*>(static_cast<empty_one*>(&a[1]));
    void* pe21 = static_cast<empty*>(static_cast<empty_two*>(&a[1]));
    std::cout << "address of non_empty[1]: " << &a[1] << std::endl;
    std::cout << "address of empty of empty_one: " << pe11 << std::endl;
    std::cout << "address of empty of empty_two: " << pe21 << std::endl;
}

On vc,

pe20 == pe11. (test1)

Can two sub-objects of two objects have the same address? Is this conformant?

Besides,

pe20 >= &a[0] + sizeof(a[0]) (test2)

Can the address of an sub-object passes the end of an object ?

On g++, above two tests does not hold.

EDIT: In c++0x standard draft, 1.8/6,

Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies. Two distinct objects that are neither bit-fields nor base class subobjects of zero size shall have distinct addresses

The standard requires that two objects have different address when they are neither bit-fields nor base class subobjects of zero size. But it doesn't require that two sub-objects of zero size cannot have same address. So test1 can be true ?

like image 328
ashen Avatar asked Nov 05 '22 04:11

ashen


1 Answers

pe10 == pe11. Can two sub-objects of two objects have the same address? Is this conformant?

No, two different objects cannot have same address. If they've, the compiler is not Standard Complaint.

By the way, which version of VC++ you're using? I'm using MSVC++2008, and it's output is this:

alt text

I think, you meant pe20==pe11? If so, then this also is wrong, non-standard. MSVC++2008 compiler has bug!

GCC is correct; see the output yourself : http://www.ideone.com/Cf2Ov


Similar topic:

When do programmers use Empty Base Optimization (EBO)

like image 183
Nawaz Avatar answered Nov 13 '22 19:11

Nawaz