xem xét lớp phân cấp này:Tại sao không trình biên dịch C++ tối ưu hóa dynamic_cast này từ một lớp học cuối cùng?
struct Animal { virtual ~Animal(); };
struct Cat : virtual Animal {};
struct Dog final : virtual Animal {};
sự hiểu biết của tôi là đưa final
trên class Dog
đảm bảo rằng không ai có thể tạo ra một lớp kế thừa từ Dog
, trong đó, hệ quả tất yếu, có nghĩa là không ai có thể tạo ra một lớp mà LÀ-A Dog
và IS-A Cat
cùng một lúc.
Hãy xem xét hai dynamic_cast
s này:
Dog *to_final(Cat *c) {
return dynamic_cast<Dog*>(c);
}
Cat *from_final(Dog *d) {
return dynamic_cast<Cat*>(d);
}
GCC, ICC, và MSVC bỏ qua final
vòng loại và tạo ra một cuộc gọi đến __dynamic_cast
; điều này thật đáng tiếc nhưng không đáng ngạc nhiên.
gì làm tôi ngạc nhiên là Clang và Zapcc cả generate mã tối ưu cho from_final
("luôn luôn trả nullptr"), nhưng tạo ra một cuộc gọi đến __dynamic_cast
cho to_final
.
Đây có phải là thực sự là một cơ hội tối ưu hóa nhỡ (trong một trình biên dịch mà rõ ràng ai đó đặt một số nỗ lực vào tôn trọng final
vòng loại trong phôi), hoặc là tối ưu hóa không thể trong trường hợp này vì một lý do tế nhị mà tôi vẫn không nhìn thấy?
Tôi đoán là tình huống này không phát sinh thường xuyên cho hầu hết các trình biên dịch phải lo lắng quá nhiều về nó. Việc tối ưu hóa được thực hiện để đáp ứng nhu cầu chung về hiệu quả trong thế giới thực. – cdhowie
@cdhowie: Bạn có thể đúng; nhưng những gì cho tôi tạm dừng là ai đó rõ ràng * đã làm * đi đến những rắc rối của việc viết một tối ưu hóa Clang trong trường hợp 'from_final'.Các trường hợp 'to_final' là đối xứng (đặc biệt là trong điều khoản của codegen, nơi mà nó kéo typeinfo cho cả hai loại), nhưng chưa biết ai đó đã làm * không * thêm tối ưu hóa đối xứng. "Tối ưu hóa một cách rõ ràng được thực hiện một nửa" xuất hiện vào não của tôi hơn là "không có tối ưu hóa nào cả" (xem GCC, ICC, MSVC). – Quuxplusone