【发布时间】:2011-01-23 03:57:12
【问题描述】:
下面是对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++ 上,以上两个测试不成立。
编辑:在 c++0x 标准草案,1.8/6,
除非对象是位域或大小为零的基类子对象,否则该对象的地址就是它占用的第一个字节的地址。既不是位字段也不是零大小的基类子对象的两个不同对象应具有不同的地址
标准要求两个对象在既不是位域也不是零大小的基类子对象时具有不同的地址。但这并不要求两个大小为零的子对象不能具有相同的地址。那么 test1 可以是真的吗?
【问题讨论】:
-
我认为您可以放心地将它提交给 MSVC 团队(除非它已经在脑海中)。
标签: c++ g++ visual-c++