5

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 ?

ashen
  • 807
  • 9
  • 24

2 Answers2

1

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)

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 1
    I just made a typo in my post, where pe10 in two tests should be pe20. WRT your output, now pe20 == pe11, which should not happen, right ? – ashen Jan 23 '11 at 04:27
1

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

Nopes!

Size of an empty class cannot be zero because in that case two objects of the same class would be having the same address which is not possible.

Similarly two sub-objects of two different objects cannot have the same address. Your compiler is not conformant. Change it!

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345