下面是一个关于ebco的简单测试,我在vc9和g ++上编译了它。两个编译器的输出都不相同。我想知道的是,vc的行为是否一致。空基类优化
#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;
}
在VC,
pe20 == pe11. (test1)
两个对象的两个子对象可以有相同的地址?这是否符合?
此外,
pe20 >= &a[0] + sizeof(a[0]) (test2)
可以在子对象的地址传递一个对象的结束?
在g ++上,上面的两个测试不成立。
EDIT:C++ 0x中标准草案,1.8/6,
除非对象是一个位字段或大小为零的基类子对象,该对象的地址是它占据的第一个字节的地址。既不是位字段也不大小为零的基类的子对象两个不同的对象应具有不同的地址
该标准要求两个对象具有不同的地址时,它们既不位字段也不基零大小的类子对象。但它不要求两个零大小的子对象不能有相同的地址。那么test1可以是真的吗?
我认为你可以安全地把它带到MSVC团队(除非它已经存在)。 – 2011-01-23 13:23:35