2012-04-12 23 views
24

Tôi chỉ tự hỏi tại sao tên mangling không bao giờ được chuẩn hóa theo chuẩn C++. Rõ ràng có các thuật toán mangling tên khác nhau làm tổn thương khả năng tương tác [1] và tôi không thấy bất kỳ lợi thế nào của việc thực hiện nó.Tại sao tên mangling không được chuẩn hóa

Tức là, ngược lại để nói quy ước gọi hoặc kích thước của nguyên thủy bản thân máy không quan tâm hoặc thậm chí biết cách gọi hàm. Vậy tại sao nó không được tiêu chuẩn hóa và tại sao nó vẫn chưa được chuẩn hóa? Các trình biên dịch đã thay đổi các quy tắc trong quá khứ giữa các phiên bản.

[1] tất cả những người xuất khẩu chức năng như extern "C" nói khối lượng.

+11

Mang tên mang tiêu chuẩn chỉ phục vụ để mang lại cho bạn cảm giác an toàn giả, bởi vì bạn cũng phải chuẩn hóa ABI để có khả năng tương thích phù hợp. Và ủy ban tiêu chuẩn C++ dường như không nằm trong ngành kinh doanh tiêu chuẩn hóa ABI. –

+3

+1 @Raymond - nói dối bản thân về khả năng tương tác là tin xấu khắp nơi. Nó giống như dựa vào hành vi không xác định. Chắc chắn, bạn * nghĩ * nó hoạt động, nhưng nó thực sự không. –

+0

Đúng, đồng ý về C++ ABI sẽ khó hơn nhiều so với C.Hơi ảm đạm: Điều gì chính xác trong câu hỏi này không được coi là phù hợp cho SO bởi 3 người? Sau khi tất cả có khá rõ ràng tồn tại một câu trả lời khác biệt tốt như đã được hiển thị. – Voo

Trả lời

19

Tiêu chuẩn không giải quyết chi tiết triển khai. Có rất nhiều, nhiều thứ phụ thuộc vào việc triển khai và ngăn chương trình làm việc cùng nhau: cách bố trí các lớp học, cấu trúc của vtable, v.v. Nói chung, trình biên dịch sẽ thay đổi tên mang tên nếu chúng thay đổi bất kỳ cái nào trong số này. Điều này là có chủ ý, vì nó ngăn mã sẽ không hoạt động khi liên kết.

Có thể có một nền tảng nhất định để xác định C++ ABI; tất cả các trình biên dịch tuân thủ nó sẽ sử dụng các triển khai tương thích và có một tên mang tên chung là . Tuy nhiên, đây là vấn đề đối với nhà cung cấp nền tảng, tuy nhiên, ; vì bất kỳ lý do gì, rất ít nhà cung cấp đã xác định một C++ ABI.

Và lý do extern "C" hoạt động là vì hầu như tất cả các nền tảng đều xác định một ABI C.

+2

Cần thêm rằng ngay cả khi mangling đã được chuẩn hóa,' extern "C" 'sẽ là cần thiết, bởi vì C không làm bất kỳ mangling và C + + có để hỗ trợ chức năng quá tải, do đó, các biểu tượng là khác nhau trong mọi trường hợp. –

+3

@JanHudec Nó không thực sự được xác định rõ những gì 'extern" C "' có nghĩa là. Điều đó có nghĩa là gì trên một nền tảng không có trình biên dịch C, chẳng hạn? Tuy nhiên, trong thực tế, hầu hết, nếu không phải tất cả các nền tảng đều định nghĩa một C ABI, và 'extern" C "' có nghĩa là tuân theo điều đó. Và ở đây, quá, tên mangling không phải là vấn đề duy nhất; Tôi đã làm việc trên các nền tảng mà các biến thứ tự được đẩy lên ngăn xếp khác nhau giữa C và C++. (Ngoài ra, hầu hết các trình biên dịch C mà tôi đã sử dụng đều mang tên mangle. Đơn giản hơn nhiều so với C++.) –

15

Chuẩn không thực sự yêu cầu mang tên. Đối với vấn đề đó, tiêu chuẩn không yêu cầu số dấu chấm động IEEE, hoặc số nguyên bổ sung twos hoặc bất kỳ số nào khác.

Cho đến khi có được một ABI rộng rãi nó có thể dựa vào, GCC actually went out of its way to use a different name mangling scheme hơn đối thủ cạnh tranh của nó:

G ++ không làm tên mangling trong cùng một cách như khác C++ biên dịch. Điều này có nghĩa là các tệp đối tượng được biên dịch với một trình biên dịch không thể được sử dụng với một trình biên dịch khác.

Hiệu ứng này là cố ý, để bảo vệ bạn khỏi các vấn đề phức tạp hơn. Các trình biên dịch khác với nhiều chi tiết bên trong của việc thực hiện C++, bao gồm: các cá thể lớp được trình bày như thế nào, bao nhiêu thừa kế được thực hiện và các cuộc gọi hàm ảo được xử lý như thế nào. Nếu mã hóa tên được thực hiện giống nhau, các chương trình của bạn sẽ liên kết với các thư viện được cung cấp từ các trình biên dịch khác - nhưng các chương trình sau đó sẽ sụp đổ khi chạy. Các thư viện không tương thích sau đó được phát hiện tại thời gian liên kết, thay vì ở thời gian chạy.

Tên mangling cũng phức tạp hơn nhiều người lập trình nhận ra. Ví dụ như tiêu chuẩn sẽ chỉ định acceptable calling conventions for all platforms that C++ could run on như thế nào? Hệ thống RISC có nên được yêu cầu hỗ trợ x86 stdcall mặc dù các hệ thống RISC thường vượt qua đối số của chúng trong sổ đăng ký thay vì trên ngăn xếp không?

Các vấn đề liên quan