2011-01-23 41 views
5

Dưới đây là một thử nghiệm đơn giản trên ebco, tôi đã biên dịch nó trên cả vc9 và g ++. Các kết quả đầu ra khác nhau trên cả hai trình biên dịch. Điều tôi muốn biết là liệu hành vi của vc có phù hợp hay không.tối ưu hóa lớp cơ sở trống

#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) 

thể hai tiểu đối tượng của hai đối tượng có cùng địa chỉ? Người tuân thủ này?

Bên cạnh đó,

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

địa chỉ của một đối tượng phụ Can đi cuối của một đối tượng?

Trên g ++, trên hai thử nghiệm không giữ.

EDIT: Trong C++ 0x tiêu chuẩn dự thảo, 1,8/6,

Trừ khi một đối tượng là một chút-lĩnh vực hoặc một subobject lớp cơ sở của kích thước không, địa chỉ của đối tượng đó là địa chỉ của byte đầu tiên nó chiếm. Hai đối tượng riêng biệt nhưng không phải là bit lĩnh vực cũng không subobjects lớp cơ sở của kích thước không phải có địa chỉ riêng biệt

Các tiêu chuẩn yêu cầu hai đối tượng có địa chỉ khác nhau khi họ đang có không bit lĩnh vực cũng không căn cứ subobjects lớp kích thước zero. Nhưng nó không yêu cầu hai đối tượng phụ có kích thước bằng 0 không thể có cùng địa chỉ. Vì vậy, test1 có thể đúng?

+0

Tôi nghĩ bạn có thể mang nó đến nhóm MSVC một cách an toàn (trừ khi nó đã sẵn sàng). –

Trả lời

1

pe10 == pe11. Hai đối tượng phụ có thể là hai đối tượng có cùng một địa chỉ không? Có phải tuân thủ này không?

Không, hai đối tượng khác nhau không thể có cùng địa chỉ. Nếu có, trình biên dịch không phải là Khiếu nại Chuẩn.

Nhân tiện, bạn đang sử dụng phiên bản VC++ nào? Tôi đang sử dụng MSVC++ 2008, và nó ra là thế này:

alt text

Tôi nghĩ rằng, bạn có nghĩa là pe20==pe11? Nếu vậy, thì điều này cũng sai, không chuẩn. Trình biên dịch MSVC++ 2008 có lỗi!

GCC là chính xác; thấy đầu ra cho mình: http://www.ideone.com/Cf2Ov


tương tự chủ đề:

When do programmers use Empty Base Optimization (EBO)

+2

Điều đó có vẻ rất bị hỏng, vì 'pe20' và' pe11' dường như có cùng một địa chỉ .... –

+1

Tôi vừa tạo lỗi đánh máy trong bài đăng của mình, trong đó pe10 trong hai thử nghiệm phải là pe20. WRT đầu ra của bạn, bây giờ pe20 == pe11, mà không nên xảy ra, phải không? – ashen

+1

@ Chris: Tôi nhận thấy điều đó. Vì vậy, cập nhật bài viết của tôi. – Nawaz

1

pe10 == pe11. Hai đối tượng phụ của hai đối tượng có cùng địa chỉ không? Người tuân thủ này?

Nopes!

Kích thước của một lớp học trống không thể không bởi vì trong trường hợp đó hai đối tượng cùng lớp sẽ có cùng một địa chỉ mà không phải là có thể.

Tương tự hai đối tượng con của hai đối tượng khác nhau không thể có cùng địa chỉ. Trình biên dịch của bạn không phù hợp. Thay đổi nó!

+0

Một lỗi đánh máy trong bài viết của tôi, xin lỗi, tôi đã sửa nó. pe10 phải là pe20 ... – ashen

+1

@ Alex: Vẫn không đúng. Trình biên dịch lỗi buggy. –