Sử dụng các trình biên dịch và phiên bản ngôn ngữ C ++ khác nhau khi phát triển một tệp thực thi duy nhất


15

Công ty chúng tôi sẽ mua một đoạn mã nguồn lớn và rất phức tạp cho thông tin vệ tinh.

Nó được mã hóa trong C ++ và chúng tôi sẽ mã bổ sung cho nó, cũng trong C ++, liên kết mã của chúng tôi với mã đã mua thành một đơn vị thực thi duy nhất.

  • Có cần thiết phải sử dụng cùng một trình biên dịch và cùng một phiên bản trình biên dịch như đã được sử dụng để phát triển mã đã mua không?

  • Có cần thiết phải sử dụng cùng một phiên bản C ++ như mã đã mua không? Nếu nó không được sử dụng vào năm 2014, chúng tôi _might_ muốn sử dụng một số tính năng của nó, nhưng không phải nếu có thể có một số vấn đề với trộn phiên bản khác nhau.

Về lý thuyết, tất nhiên, nó không phải là vấn đề, đặc biệt là phiên bản ngôn ngữ, nhưng có thể hình dung rằng các phiên bản khác nhau của trình biên dịch sẽ tạo ra mã đối tượng khác nhau, có khả năng dẫn đến sự khác biệt về thời gian, v.v.

Chúng ta nên biết điều gì?


7
Tôi hy vọng bạn không chỉ mua mã nguồn, mà một số hỗ trợ (bởi những người đủ điều kiện) trên đó.
Basile Starynkevitch

1
Thật vậy, chúng tôi là. Và, tất nhiên, tôi cũng đã hỏi câu hỏi này của nhà cung cấp. Nhưng tôi nghĩ rằng nó sẽ là một điểm thảo luận tốt ở đây, và là một tài liệu tham khảo tốt trong tương lai cho những người khác trong tương lai.
Mawg nói rằng phục hồi Monica

2
Bạn đang nói về việc biên dịch mã bên thứ ba bằng trình biên dịch không được hỗ trợ hay bạn đang nói về việc biên dịch các phần mã khác nhau bằng các trình biên dịch khác nhau (ví dụ: sử dụng mã được hỗ trợ cho mã bạn mua và mã mới hơn cho mã của riêng bạn và sau đó liên kết chúng)? Hay là quyết định giữa những phần của câu hỏi?
jpmc26

3
Ngay cả phiên bản ngôn ngữ cũng có thể quan trọng, xem gcc.gnu.org/wiki/Cxx11AbiCompabilities để biết danh sách các phiên bản trình biên dịch (cũ hơn) và những khác biệt nhỏ trong ABI. Nói cách khác: cùng một trình biên dịch, nhưng cài đặt ngôn ngữ c ++ khác nhau (c ++ 03 s c ++ 11) có thể có vấn đề.
André

2
Và với MSVC, nói chung không an toàn khi vượt qua các đối tượng thư viện tiêu chuẩn xuyên qua ranh giới thư viện (động). Xem ví dụ stackoverflow.com/q/5661738/417197
André

Câu trả lời:


9

Có cần thiết phải sử dụng cùng một trình biên dịch và cùng một phiên bản trình biên dịch như đã được sử dụng để phát triển mã đã mua không?

Nó phụ thuộc.

Trình biên dịch tạo mã nhắm mục tiêu ABI. Một số người đang sử dụng ABI phổ biến (ví dụ: nếu tôi không nhầm, cả mục tiêu clang ++ và g ++ để gọi là Itanium ABI) và bạn nên - có thể có lỗi ngăn bạn làm như vậy - có thể sử dụng mã đối tượng từ cả hai trong cùng một chương trình (tất nhiên giả sử rằng bạn đang sử dụng các phiên bản nhắm đến cùng một phiên bản ABI). Điều tương tự cũng đúng giữa phiên bản trình biên dịch: một số chú ý nhiều hơn để giữ cùng ABI giữa phiên bản so với phiên bản khác. Rõ ràng, tất cả họ đều cần đôi khi thay đổi ABI và họ có thể bị buộc phải làm như vậy theo cách không tương thích. Và rõ ràng, một số cài đặt như lựa chọn tiêu chuẩn ngôn ngữ có thể có ảnh hưởng đến sự lựa chọn ABI.

Sau đó là vấn đề của thư viện tiêu chuẩn. Bản thân các trình biên dịch (hoặc các phiên bản khác nhau của cùng một trình biên dịch) có thể sử dụng cùng một ABI và thư viện chuẩn của chúng có thể không tương thích (và một số trình biên dịch như clang ++ có thể sử dụng được với một số thư viện chuẩn). Có thể làm cho nó hoạt động có thể phụ thuộc vào những gì được sử dụng trong giao diện.

Nói cách khác, bạn phải đào và tìm thông tin cho trường hợp cụ thể mà bạn đang tham gia. Là một điểm khởi đầu và một ví dụ về loại thông tin bạn nên tìm, đây là thông tin được cung cấp bởi libstdc ++ (thư viện được sử dụng bởi g ++ và trong một số cấu hình của clang ++)


10
ABI = Giao diện nhị phân ứng dụng
Simon B

2
Câu trả lời này là về khả năng tương thích của mã đối tượng. OP đang mua mã nguồn .
Cuộc đua nhẹ nhàng với Monica

7
@LightnessRacesinOrbit Câu hỏi nói về việc sử dụng các trình biên dịch khác nhau để tạo ra một tệp thực thi duy nhất. Nó không phải là một bước nhảy vọt lớn để nghĩ, "Họ có nghĩa là biên dịch mã của bên thứ ba với một trình biên dịch (có thể là một 'được hỗ trợ') và mã của riêng họ với một trình biên dịch khác (có thể là một trình biên dịch mới hơn)." (Đây chắc chắn là điều tôi hiểu OP sẽ hỏi; nếu bạn đọc khác đi, bạn có thể muốn yêu cầu OP làm rõ.) Trong khả năng đó hoặc những điều tương tự khác, tính tương thích của mã đối tượng có vẻ rất phù hợp.
jpmc26

1
@ jpmc26: "Đây chắc chắn là điều tôi hiểu OP sẽ hỏi; nếu bạn đọc nó khác đi, bạn có thể muốn yêu cầu OP làm rõ." OP tuyên bố rõ ràng rằng công ty của họ "sẽ mua một đoạn mã nguồn lớn và rất phức tạp". Hơn nữa, với các câu lệnh như "có thể hiểu được rằng các phiên bản khác nhau của trình biên dịch sẽ tạo ra mã đối tượng khác nhau, có khả năng dẫn đến sự khác biệt về thời gian", họ đang hỏi về những thay đổi khi họ biên dịch mã đã mua với các công cụ khác nhau, không chỉ riêng chúng. Tôi không nghĩ có nhiều chỗ để diễn giải ở đó!
Cuộc đua nhẹ nhàng với Monica

8

Có cần thiết phải sử dụng cùng một trình biên dịch và cùng một phiên bản trình biên dịch như đã được sử dụng để phát triển mã đã mua không? Có cần thiết phải sử dụng cùng một phiên bản C ++ như mã đã mua không?

Đây không phải là một câu hỏi kỹ thuật. Đó là một câu hỏi pháp lý về những gì bạn viết trong hợp đồng của bạn. Đảm bảo nhà cung cấp phần mềm cung cấp cho bạn phiên bản được bảo đảm bởi anh ta để có thể sử dụng được trong môi trường của bạn. Nếu không, sẽ luôn có một rủi ro nhất định gặp rắc rối với trình biên dịch, phiên bản trình biên dịch hoặc phiên bản ngôn ngữ khác nhau.

Điều này đặc biệt quan trọng khi bạn mua thành phần hoặc các bộ phận của nó dưới dạng nguồn đóng. Ngay cả khi nhà cung cấp của bạn đảm bảo bạn có thể sử dụng thành phần với môi trường trình biên dịch hiện tại của mình, anh ta có đảm bảo anh ta sẽ cung cấp cho bạn các bản cập nhật nếu bạn muốn chuyển sang phiên bản trình biên dịch mới hơn trong tương lai không? Nếu bạn không có quyền truy cập vào mã nguồn đầy đủ, có lẽ bạn sẽ không gặp nhiều may mắn khi tự mình cố gắng giải quyết bất kỳ vấn đề tương thích nào. Đó là lý do tại sao bạn không nên chỉ mua phần mềm mà còn nghĩ về hợp đồng bảo trì dài hạn với nhà cung cấp của bạn.


Đây thực sự là một lời khuyên khá tốt!
T. Sar - Tái lập Monica

Nó thực sự là, nhưng, than ôi, quá muộn. Khi tôi nhận xét về nhận xét của Basile, tôi cũng đã hỏi câu hỏi này của nhà cung cấp. Nhưng tôi nghĩ rằng nó sẽ là một điểm thảo luận tốt ở đây và là một tài liệu tham khảo tốt trong tương lai cho những người khác trong tương lai
Mawg nói rằng phục hồi lại

4

Công ty chúng tôi sẽ mua một đoạn mã nguồn lớn và rất phức tạp cho thông tin vệ tinh. Nó được mã hóa trong C ++ và chúng tôi sẽ mã bổ sung cho nó, cũng trong C ++, liên kết mã của chúng tôi với mã đã mua thành một đơn vị thực thi duy nhất.

Nghe hay đấy!

Có cần thiết phải sử dụng cùng một trình biên dịch và cùng một phiên bản trình biên dịch như đã được sử dụng để phát triển mã đã mua không?

Nói chung, không cần thiết. Mục đích của C ++ là hoạt động như một sự trừu tượng hóa các loại điều này, vì vậy một chương trình C ++ được viết tốt sẽ biên dịch tốt trên chuỗi công cụ của bạn giống như trên tác giả ban đầu và chương trình kết quả sẽ có kết quả tương tự. Hiệu suất có thể khác nhau, bởi vì các trình biên dịch khác nhau tốt ở những thứ khác nhau, nhưng hành vi cơ bản của chương trình không nên thay đổi.

Tuy nhiên, phần mềm được viết xấu có thể dựa vào hành vi cụ thể thực hiện hoặc thậm chí là hành vi không xác định. Nó có thể đưa ra các giả định về các loại tích hợp hoặc về độ bền của nền tảng. Ngay cả phần mềm được viết tốt cũng có thể không có lựa chọn nào ngoài việc dựa vào các tiện ích mở rộng không chuẩn không có trên chuỗi công cụ bạn đã chọn hoặc có thể làm như vậy vì đơn giản là không cần phải dành thời gian để thêm lớp khả năng di động trong khoảng thời gian dự án ban đầu.

Cuối cùng, bạn sẽ cần hỏi tác giả / nhà cung cấp mã nguồn được viết để làm gì. Nếu họ cho rằng nó được viết riêng, giả sử, Visual Studio 2015 và yêu cầu các tính năng API của Windows, có lẽ bạn nên tuân thủ điều đó. Nhưng nếu họ cho rằng đó là C ++ di động, tiêu chuẩn, thì hãy sử dụng bất kỳ trình biên dịch nào bạn thích. Hãy chắc chắn rằng thỏa thuận mua hàng của bạn bao gồm một thỏa thuận hỗ trợ để bạn có thể nhận được sự giúp đỡ miễn phí khi hóa ra nhà cung cấp đã nói dối.

Có cần thiết phải sử dụng cùng một phiên bản C ++ như mã đã mua không? Nếu nó không sử dụng 2014, chúng tôi có thể muốn sử dụng một số tính năng của nó, nhưng không có vấn đề gì với việc trộn các phiên bản khác nhau.

Có lẽ. Có lẽ.

C ++ 03 tương thích với hầu hết các phần vì vậy, nếu mã là C ++ 03, thì bạn không có vấn đề gì. (Mặc dù một số điều chỉnh có thể được yêu cầu.)

Nhưng các tính năng được giới thiệu trong C ++ 11 và C ++ 14 không tương thích ngược nên nếu nhà cung cấp đã sử dụng, giả sử, C ++ 11 lambdas và bạn cố gắng xây dựng mã của họ trong trình biên dịch C ++ 03, chỉ cần thắng 't làm việc.

Về lý thuyết, tất nhiên, nó không phải là vấn đề, đặc biệt là phiên bản ngôn ngữ, nhưng có thể hình dung rằng các phiên bản khác nhau của trình biên dịch sẽ tạo ra mã đối tượng khác nhau, có khả năng dẫn đến sự khác biệt về thời gian, v.v.

Chắc chắn rồi. Nếu mã phụ thuộc rất nhiều vào việc triển khai cụ thể để có được kết quả mong đợi, thì nhà cung cấp phải chịu trách nhiệm và thông báo cho bạn về điều đó. Vì chúng ta sống trong thế giới thực, tôi khuyên bạn nên siêng năng và hỏi họ trước.

Và tôi sẽ lặp lại những gì người khác đã nói: đảm bảo rằng bạn có một số cách truy vấn hỗ trợ, để nếu họ trình bày sai bất kỳ câu trả lời nào cho những câu hỏi này (dù cố ý hay cách khác), bạn sẽ không phải chịu chi phí kết quả.


Đáng lưu ý: liên kết không được đề cập đầy đủ trong thông số kỹ thuật của C ++. Mặc dù mã có thể biên dịch trong nhiều trình biên dịch tuân thủ, nhưng không đảm bảo rằng bạn chỉ có thể liên kết chúng với nhau và làm cho nó hoạt động.
Cort Ammon - Phục hồi Monica

1
@CortAmmon: Bạn nên / phải biên dịch tất cả các thành phần của phân phối kết quả với các bộ công cụ có chung ABI. Các tiêu chuẩn ABI nằm ngoài phạm vi của C ++. Tôi không nghĩ OP đang hỏi về việc trộn các bộ công cụ.
Cuộc đua nhẹ nhàng với Monica

2

Bạn không liên kết mã, bạn liên kết các tệp đối tượng được biên dịch.

Trong trường hợp này, có, sử dụng các trình biên dịch C ++ khác nhau (hoặc thậm chí các cài đặt như gỡ lỗi / phát hành bản dựng) hoặc các phiên bản khác nhau của chúng hoặc các thư viện chuẩn khác nhau (phiên bản) khi xây dựng các phần sẽ tương tác ở cấp nhị phân rất có khả năng phá vỡ ứng dụng nếu các bộ phận giao tiếp với nhau bằng nhiều API C.

Các tính năng như thùng chứa hoặc ngoại lệ cung cấp cùng một giao diện nhưng, ở cấp độ nhị phân, có thể được triển khai theo nhiều cách khác nhau, không tương thích.

Tuy nhiên, sử dụng một trình biên dịch khác nhau để biên dịch toàn bộ mã là một vấn đề khác. Câu hỏi cần xem xét:

  • Mã nền tảng / kiến ​​trúc nào nhắm mục tiêu?
  • Nó được viết theo tiêu chuẩn nào?
  • Nó có sử dụng bất kỳ tính năng biên dịch không chuẩn?
  • Mã có chứa các giả định cụ thể của nền tảng được mã hóa cứng (như luôn luôn xem xét rằng các con trỏ chiếm 2 byte) không?

Cũng có nguy cơ mã có thể chứa các phần dẫn đến hành vi không xác định. Chúng có thể hoạt động tốt khi sử dụng một trình biên dịch nhưng thất bại theo những cách bí ẩn khi sử dụng một trình biên dịch khác.


OP đang xây dựng mã chứ không phải nhà cung cấp. OP đang hỏi làm thế nào thay đổi môi trường xây dựng (xem nhà cung cấp) có thể ảnh hưởng đến việc tạo mã được cung cấp cùng một cơ sở mã.
Cuộc đua nhẹ nhàng với Monica

1

Có cần thiết phải sử dụng cùng một trình biên dịch và cùng một phiên bản trình biên dịch như đã được sử dụng để phát triển mã đã mua không?

Vâng, chuyển đổi trình biên dịch, có thể dẫn đến một số vấn đề; hiện tại trong công ty của tôi, chúng tôi sử dụng Clang và MSVC và chúng tôi gặp lỗi trong một trình biên dịch mà trình biên dịch kia không đánh dấu như vậy.

Có cần thiết phải sử dụng cùng một phiên bản C ++ như mã đã mua không? Nếu nó không sử dụng 2014, chúng tôi có thể muốn sử dụng một số tính năng của nó, nhưng không có vấn đề gì với việc trộn các phiên bản khác nhau.

Không cần thiết, nhưng tất nhiên trình biên dịch của bạn nên hỗ trợ phiên bản C ++ mà bạn muốn sử dụng. C ++ đảm bảo khả năng tương thích retro bắt đầu từ tất cả các phiên bản.


Khá nhiều suy nghĩ của tôi. Điều gì về các trình biên dịch trình biên dịch - nếu họ sử dụng GCC phiên bản x và mới nhất là x + 2 chẳng hạn?
Mawg nói rằng phục hồi Monica

1
Chà, nếu họ sử dụng phiên bản cũ hơn của trình biên dịch mà bạn muốn sử dụng, thì không có vấn đề gì, bởi vì không có thứ gì bị phản đối, vấn đề có thể xảy ra nếu họ sử dụng phiên bản mới hơn của trình biên dịch.
LaboPie

Nhưng bằng cách nào? Tôi cũng vậy, woudl không thích. Nhưng bạn có biết về bất kỳ loại vấn đề nào có thể xảy ra không?
Mawg nói rằng phục hồi Monica

Nhưng bạn có biết về bất kỳ loại vấn đề nào có thể xảy ra không? Nếu họ đang sử dụng một số chức năng mà trình biên dịch của chúng tôi sẽ không hỗ trợ, mã đơn giản sẽ không biên dịch.
LaboPie

1
Một phụ lục nhỏ, tất nhiên vấn đề trở nên lớn hơn nếu trình biên dịch được sử dụng từ văn phòng khác không phải là vấn đề chính. EG một trình biên dịch giao diện điều khiển cũ, hoặc một cái gì đó hoạt động với tập hợp con của ngôn ngữ.
LaboPie

1

Một vấn đề lớn khi thay đổi trình biên dịch là hành vi không xác định: Nếu mã mà bạn nhận được gọi hành vi không xác định, thì mọi thứ đều có thể - bao gồm mã hoạt động tốt và vượt qua tất cả các kiểm tra khi sử dụng trình biên dịch của chúng và rất tệ với trình biên dịch của bạn.

Điều đó có thể, nhưng trong tình huống đó, bạn cũng có thể gặp vấn đề nếu bạn thay đổi mức tối ưu hóa, sử dụng phiên bản tiếp theo của cùng một trình biên dịch, v.v. Vì vậy, không có gì bạn có thể tránh.


Đây là một lập luận tốt cho việc sử dụng lint và có thể valgrind .
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.