2011-01-23 2 views
5

Ниже приведен простой тест на 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; 
} 

На ВХ,

pe20 == pe11. (test1) 

Могут ли два суб-объекты двух объектов имеют один и тот же адрес? Согласуется ли это?

Кроме того,

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

Может адрес в подъобекта проходит конец объекта?

В g ++ выше двух тестов не выполняется.

РЕДАКТИРОВАТЬ: В C++ 0x проект стандарта, 1.8/6,

Если объект не является битовое поле или базовый класс подобъектом нулевого размера, адрес этого объекта является адрес первого байта, который он занимает. Два различных объектов, которые не являются ни битовые поля, ни базового класса подобъектами нулевого размера должны иметь различные адреса

Стандарт требует, чтобы два объекта имеют разные адреса, когда они ни битовые поля, ни базовых классов Подобъекты нулевого размера. Но это не требует, чтобы два под-объекта нулевого размера не могли иметь один и тот же адрес. Итак, test1 может быть правдой?

+0

Я думаю, что вы можете смело привести его в команду MSVC (если только это уже не так). –

ответ

1

pe10 == pe11. Может ли два под-объекта два объекта имеют одинаковый адрес? Есть это соответствие?

Нет, два разных объекта не могут иметь одинаковый адрес. Если они есть, компилятор не является стандартной жалобой.

Кстати, какую версию VC++ вы используете? Я использую MSVC++ 2008, и это выход заключается в следующем:

alt text

Я думаю, вы имели в виду pe20==pe11? Если это так, то это также неправильно, нестандартно. У компилятора MSVC++ 2008 есть ошибка!

GCC правильный; увидеть результат себя: http://www.ideone.com/Cf2Ov


Похожие темы:

When do programmers use Empty Base Optimization (EBO)

+2

Это кажется очень сломанным, поскольку 'pe20' и' pe11', похоже, имеют тот же адрес .... –

+1

Я только что сделал опечатку в своем посте, где pe10 в двух тестах должен быть pe20. WRT ваш выход, теперь pe20 == pe11, чего не должно быть, не так ли? – ashen

+1

@ Крис: Я это заметил. Так обновил мой пост. – Nawaz

1

PE10 == PE11. Может ли два под-объекта двух объектов иметь один и тот же адрес? Согласуется ли это?

Nopes!

Размер пустого класса не может быть равен нулю, так как в этом случае два объекта одного и того же класса будет таким же адресом, который не возможно.

Аналогично, два под-объекта двух разных объектов не могут иметь один и тот же адрес. Ваш компилятор не соответствует. Измени это!

+0

Опечатка в моем посте, извините, я исправил ее. pe10 должен быть pe20 ... – ashen

+1

@Alex: Тем не менее это неверно. Багги-компилятор. –

Смежные вопросы