2012-05-23 43 views
18

Tôi biết rằng trong nguyên tắc này có lẽ là hành vi không xác định, nhưng vì lợi ích của đối phó với một dự án lớn, đây là câu hỏi của tôi về GCC:Các phương ngữ GCC khác nhau có thể được liên kết với nhau không?

Giả sử tôi lập một đơn vị transation với gcc -std=c++98, và khác với -std=c++11, sử dụng chính xác cùng một trình biên dịch cài đặt. Có bất kỳ loại bảo đảm nào mà tôi có thể liên kết hai tệp đối tượng và có được một chương trình được xác định rõ không? Theo như tôi có thể nói, các vấn đề tiềm năng chỉ có thể đến từ các góc nhìn khác nhau của các tiêu đề thư viện do các macro khác nhau, và những thứ đó sẽ tốt nhất là thêm chức năng thành viên mới, nhưng không bao giờ là đối tượng thành viên các lớp thư viện chuẩn.

Điều này có giúp cho việc biên dịch các phần khác nhau của một dự án lớn hơn với các phương ngữ ngôn ngữ khác nhau có chấp nhận được không?

Cập nhật: tôi nên thêm một câu hỏi trực giao: Điều gì về việc sử dụng hai phiên bản khác nhau của GCC (nói 4.3 và 4.6), nhưng Wht tùy chọn phương ngữ cùng (-std=c++98)? Danh sách in this GCC documentation dường như gợi ý rằng thư viện tương thích theo cả hai hướng giữa 4.2.2 và 4.6.

Trả lời

10

Ưu tiên, không. Giải pháp an toàn nhất là giả định rằng tất cả của các tùy chọn trình biên dịch là giống hệt nhau, ngoại trừ khi trình biên dịch đặc biệt tài liệu rằng tùy chọn không ảnh hưởng đến khả năng tương thích nhị phân. Trong thực tế, trong việc thiếu tài liệu, có vẻ như một cược an toàn mà các tùy chọn kiểm soát cảnh báo (-W... trong g ++) sẽ không ảnh hưởng đến khả năng tương thích nhị phân, và các tùy chọn có ảnh hưởng đến việc tạo mã (mức độ ngôn ngữ, vv) có thể: g ++ thường duy trì tính tương thích trên các mức tối ưu khác nhau, trong đó VC++ không có.

Một vấn đề thực sự khác là xác định các biểu tượng tiền xử lý trong dòng lệnh. Một lần nữa, đặt cược an toàn nhất là tất cả các định nghĩa đều giống nhau, nhưng cũng một lần nữa, một số ý nghĩa thông thường là theo thứ tự: người ta khó có thể mong đợi thư viện chuẩn được biên dịch với các ký hiệu tiền xử lý được sử dụng trong dự án của bạn (những thứ như MYPROG_CONFIG_FILE_LOCATION, Nói). Mặt khác, lưu ý rằng các định nghĩa tiền xử lý của _GLIBCXX_DEBUG_GLIBCXX_DEBUG_PEDANTIC sẽ ảnh hưởng đến khả năng tương thích nhị phân (mặc dù g ++ đảm bảo rằng bạn sẽ nhận được phiên bản thư viện hoạt động với chúng nếu bạn sử dụng chúng một cách nhất quán).

Liên quan đến câu hỏi của bạn: Tôi không mong đợi sẽ ảnh hưởng nhiều đến khả năng tương thích nhị phân do phiên bản chuẩn, nhưng nó sẽ không làm tôi ngạc nhiên nếu lựa chọn ảnh hưởng đến một số ký hiệu tiền xử lý được xác định trước. tương thích nhị phân trong thư viện, nhiều như thể bạn đã biên dịch một số mô-đun với _GLIBCXX_DEBUG và một số không có. Nó có thể hoạt động, nhưng tôi sẽ không dựa vào nó.

+1

"người ta khó có thể mong đợi các thư viện chuẩn đã được biên soạn với các biểu tượng tiền xử lý được sử dụng trong dự án của bạn" - và ngay cả khi nó đã được, và giả sử trong một khoảnh khắc mà vĩ mô 'MYPROG_CONFIG_FILE_LOCATION' được sử dụng trong' memset.c', nghĩa là định nghĩa 'memset.c' hoàn toàn không liên quan đến ý nghĩa của nó trong chương trình của bạn. Vì vậy, nếu biên dịch 'memset.c' có/không có' MYPROG_CONFIG_FILE_LOCATION' tạo sự khác biệt cho khả năng tương thích nhị phân, thì nó sẽ làm như vậy độc lập cho dù chương trình của bạn có xảy ra cũng sử dụng 'MYPROG_CONFIG_FILE_LOCATION' hay không. –

+0

@SteveJessop Có. Ngay cả khi nó đã được, nó phải được minh bạch cho bạn. Trong thực tế, tất cả các ký hiệu tiền xử lý trong không gian tên của bạn (tức là không bắt đầu bằng dấu gạch dưới và không chứa hai dấu gạch dưới liền kề) _should_ an toàn. Các ký hiệu tiền xử lý trong không gian tên triển khai, như '_GLIBCXX_DEBUG', sẽ không được. –

3

Tôi biết rằng trong nguyên tắc này có lẽ là hành vi không xác định,

Nó không phải.

Giả sử tôi biên dịch một đơn vị chuyển đổi với gcc -std=c++98 và một đơn vị khác có -std=c++11, sử dụng cài đặt trình biên dịch tương tự. Có bất kỳ loại bảo đảm nào mà tôi có thể liên kết hai tệp đối tượng và có được một chương trình được xác định rõ không?

Vâng, đây được hỗ trợ và công trình (có những ngoại lệ, như tạo điều kiện cho Chế độ gỡ lỗi trong một đối tượng và không phải là khác, hoặc sử dụng tùy chọn rõ ràng-ABI thay đổi như -fshort-enums trong một và không phải là khác, nhưng điều đó nên được rõ ràng bởi vì điều đó sẽ không hoạt động ngay cả khi bạn sử dụng cùng một tùy chọn -std cho cả hai đối tượng).

Theo như tôi có thể nói, các vấn đề tiềm năng chỉ có thể đến từ các chế độ xem khác nhau của các tiêu đề thư viện do các macro khác nhau và lần lượt sẽ thêm các chức năng thành viên mới, nhưng không bao giờ là đối tượng thành viên các lớp thư viện chuẩn.

Phải.

Điều này có giúp cho việc biên dịch các phần khác nhau của dự án lớn hơn với các phương ngữ ngôn ngữ khác nhau có chấp nhận được không?

Đối với GCC, có, tuyệt đối. Vì bằng chứng là không sao, hãy xem xét rằng bản thân số libstdc++.so chứa một số đối tượng được xây dựng với -std=c++98 và một số được xây dựng với -std=c++14.

Cập nhật: Tôi nên thêm câu hỏi trực giao: Điều gì về việc sử dụng hai phiên bản khác nhau của GCC (nói 4.3 và 4.6), nhưng có cùng tùy chọn phương ngữ (-std = C++ 98)? Việc liệt kê trong tài liệu GCC này dường như gợi ý rằng thư viện tương thích theo cả hai hướng giữa 4.2.2 và 4.6.

Không theo cả hai hướng, bạn cần sử dụng libstdc++.so từ GCC 4.6 (hoặc mới hơn), vì đối tượng được biên dịch với phiên bản đó có thể phụ thuộc vào các ký hiệu được giới thiệu trong phiên bản mới hơn và không có trong thư viện cũ hơn libstdc++.so.

Một số thông tin liên quan tại https://stackoverflow.com/a/49119902/981959

0

Ngôn ngữ ABI là như nhau, nhưng STL ABI là khác nhau. Xem https://gcc.gnu.org/wiki/Cxx11AbiCompatibility

Vì vậy, bạn không nên trộn các thư viện được biên dịch với -std = C++ 98 -std = C++ 11. Bạn có thể gặp sự cố khi truyền dữ liệu qua các ranh giới hình ảnh.

(Nó có thể hoạt động nếu bạn chỉ gọi các hàm "C" bên ngoài và chỉ chuyển POD).

Cũng thấy liên quan: Mixing different C++ standards with GCC

+0

Trang wiki đó dường như không được cập nhật :-( –

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