【问题标题】:empty base class optimization空基类优化
【发布时间】: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++


【解决方案1】:

pe10 == pe11。可以两个子对象 两个对象有相同的地址?是 这个符合吗?

不,两个不同的对象不能有相同的地址。如果有,则编译器不是标准投诉。

顺便问一下,您使用的是哪个版本的 VC++?我正在使用 MSVC++2008,它的输出是这样的:

我想,你是说pe20==pe11?如果是这样,那么这也是错误的,不标准的。 MSVC++2008编译器有bug!

GCC 是正确的;自己看输出:http://www.ideone.com/Cf2Ov


类似话题:

When do programmers use Empty Base Optimization (EBO)

【讨论】:

  • 我刚刚在我的帖子中打错了,两次测试中的 pe10 应该是 pe20。 WRT 你的输出,现在是 pe20 == pe11,这不应该发生,对吧?
【解决方案2】:

pe10 == pe11。两个对象的两个子对象可以有相同的地址吗?这符合吗?

Nopes!

空类的大小不能为零,因为在这种情况下,同一类的两个对象将具有相同的地址,这是不可能的。

同样,两个不同对象的两个子对象不能有相同的地址。您的编译器不符合要求。改变它!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-03
    • 2020-04-26
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多