Hãy xem xét ví dụ sau:C++: lớp khác nhau có cùng tên trong các đơn vị dịch khác nhau
// usedclass1.hpp
#include <iostream>
class UsedClass
{
public:
UsedClass() { }
void doit() { std::cout << "UsedClass 1 (" << this << ") doit hit" << std::endl; }
};
// usedclass2.hpp
#include <iostream>
class UsedClass
{
public:
UsedClass() { }
void doit() { std::cout << "UsedClass 2 (" << this << ") doit hit" << std::endl; }
};
// object.hpp
class Object
{
public:
Object();
};
// object.cpp
#include "object.hpp"
#include "usedclass2.hpp"
Object::Object()
{
UsedClass b;
b.doit();
}
// main.cpp
#include "usedclass1.hpp"
#include "object.hpp"
int main()
{
Object obj;
UsedClass a;
a.doit();
}
mã biên dịch mà không cần bất kỳ trình biên dịch hoặc mối liên kết lỗi. Nhưng sản lượng là xa lạ đối với tôi:
gcc (Red Hat 4.6.1-9) trên Fedora x86_64 không có tối ưu hóa [EG1]:
UsedClass 1 (0x7fff0be4a6ff) số tiền rất ít hit
UsedClass 1 (0x7fff0be4a72e) số tiền rất ít nhấngiống như [EG1] nhưng với -O2 tùy chọn kích hoạt [EG2]:
UsedClass 2 (0x7fffcef79fcf) số tiền rất ít nhấn
UsedClass 1 (0x7fffcef79fff) số tiền rất ít nhấnmsvc2005 (14.00.50727.762) trên Windows XP 32bit không có tối ưu hóa [EG3] :
UsedClass 1 (0012FF5B) số tiền rất ít nhấn
UsedClass 1 (0012FF67) số tiền rất ít nhấngiống như [EG3] nhưng với/O2 (hoặc/Sửu) được kích hoạt [EG4]:
UsedClass 1 (0012FF73) số tiền rất ít nhấn
UsedClass 1 (0012FF7F) số tiền rất ít nhấn
tôi mong chờ hoặc là một lỗi mối liên kết (giả sử quy tắc ODR bị vi phạm) hoặc đầu ra như trong [EG2] (mã được inlined, không có gì được xuất khẩu từ translati trên đơn vị, quy tắc ODR được giữ). Vì vậy, câu hỏi của tôi:
- Tại sao các đầu ra [EG1], [EG3], [EG4] có thể?
- Tại sao tôi nhận được các kết quả khác nhau từ các trình biên dịch khác nhau hoặc thậm chí từ cùng một trình biên dịch? Điều đó làm cho tôi nghĩ rằng tiêu chuẩn bằng cách nào đó không xác định hành vi trong trường hợp này.
Cảm ơn bạn đã đề xuất, nhận xét và diễn giải tiêu chuẩn.
Cập nhật
Tôi muốn hiểu hành vi của trình biên dịch. Chính xác hơn, tại sao không có lỗi nào được tạo ra nếu ODR bị vi phạm. Giả thuyết là vì tất cả các hàm trong các lớp UsedClass1 và UsedClass2 được đánh dấu là nội tuyến (và do đó C++ 03 3.2 là không vi phạm) trình liên kết không báo cáo lỗi, nhưng trong trường hợp này kết quả đầu ra [EG1], [EG3], [EG4] có vẻ lạ.
ODR bị vi phạm và bạn không được đảm bảo lỗi liên kết khi điều đó xảy ra. Hành vi không xác định. –
Tôi không thể trả lời bạn câu hỏi liên quan đến các tiêu chuẩn nhưng lý do tại sao chúng tôi có không gian tên. – 111111