Menggunakan berbagai kompiler C ++ dan versi bahasa saat mengembangkan satu executable


15

Perusahaan kami akan membeli sepotong kode sumber yang besar dan sangat kompleks untuk komunikasi satelit.

Ini dikodekan dalam C ++ dan kami akan menambahkan kode untuk itu, juga di C ++, menghubungkan kode kami dengan kode yang dibeli ke dalam satu unit yang dapat dieksekusi.

  • Apakah kita perlu menggunakan kompiler yang sama dan versi kompiler yang sama seperti yang digunakan untuk mengembangkan kode yang dibeli?

  • Apakah kita perlu menggunakan versi C ++ yang sama dengan kode yang dibeli? Jika tidak menggunakan 2014, kami _might_ ingin menggunakan beberapa fitur itu, tetapi tidak jika mungkin ada beberapa masalah dengan pencampuran versi yang berbeda.

Secara teori, tentu saja, seharusnya tidak menjadi masalah, terutama versi bahasa, tetapi dapat dibayangkan bahwa versi berbeda dari kompiler akan menghasilkan kode objek yang berbeda, yang berpotensi mengarah pada perbedaan waktu, dll.

Apa yang harus kita waspadai?


7
Saya harap Anda tidak hanya membeli kode sumber, tetapi beberapa dukungan (oleh orang-orang yang memenuhi syarat) di atasnya.
Basile Starynkevitch

1
Memang benar. Dan, tentu saja, saya telah menanyakan pertanyaan pemasok ini juga. Tapi saya pikir itu akan menjadi titik diskusi yang baik di sini, dan referensi masa depan yang baik untuk orang lain di masa depan.
Mawg mengatakan mengembalikan Monica

2
Apakah Anda berbicara tentang kompilasi kode pihak ketiga menggunakan kompiler yang tidak didukung, atau apakah Anda berbicara tentang kompilasi bagian kode yang berbeda menggunakan kompiler yang berbeda (misalnya menggunakan yang didukung untuk kode yang Anda beli dan yang lebih baru untuk kode Anda sendiri dan kemudian menghubungkan mereka)? Atau memutuskan antara bagian dari pertanyaan itu?
jpmc26

3
Bahkan versi bahasa mungkin penting, lihat gcc.gnu.org/wiki/Cxx11AbiCompatibility untuk daftar versi kompiler (lama) dan perbedaan kecil dalam ABI. Dengan kata lain: kompiler yang sama, tetapi pengaturan bahasa c ++ yang berbeda (c ++ 03 s c ++ 11) mungkin penting.
André

2
Dan dengan MSVC, secara umum tidak aman untuk melewati objek perpustakaan standar melintasi batas-batas perpustakaan (dinamis). Lihat misalnya stackoverflow.com/q/5661738/417197
André

Jawaban:


9

Apakah kita perlu menggunakan kompiler yang sama dan versi kompiler yang sama seperti yang digunakan untuk mengembangkan kode yang dibeli?

Tergantung.

Compiler menghasilkan kode yang menargetkan ABI. Beberapa menggunakan ABI umum (misalnya, jika saya tidak salah, baik dentang ++ dan g ++ target disebut Itanium ABI) dan Anda harus - mungkin ada bug yang mencegah Anda melakukannya - dapat menggunakan kode objek dari keduanya dalam program yang sama (dengan asumsi tentu saja Anda menggunakan versi yang menargetkan versi ABI yang sama). Hal yang sama berlaku antara versi kompiler: beberapa lebih memperhatikan untuk menjaga ABI yang sama di antara versi daripada yang lain. Jelas, mereka semua kadang-kadang membutuhkan perubahan ABI, dan mereka mungkin terpaksa melakukannya dengan cara yang tidak kompatibel. Dan jelas, beberapa pengaturan seperti pilihan standar bahasa mungkin memiliki pengaruh pada pilihan ABI.

Lalu ada masalah perpustakaan standar. Kompiler (atau versi berbeda dari kompiler yang sama) sendiri dapat menggunakan ABI yang sama, namun pustaka standarnya mungkin tidak kompatibel (dan beberapa kompiler seperti dentang ++ mungkin dapat digunakan dengan beberapa pustaka standar). Mampu membuatnya berfungsi mungkin tergantung pada apa yang digunakan di antarmuka.

Dengan kata lain, Anda harus menggali dan menemukan informasi untuk kasus khusus Anda. Sebagai titik awal dan contoh jenis informasi apa yang harus Anda cari, berikut adalah informasi yang disediakan oleh libstdc ++ (perpustakaan yang digunakan oleh g ++ dan dalam beberapa konfigurasi oleh dentang ++)


10
ABI = Antarmuka Biner Aplikasi
Simon B

2
Jawaban ini adalah tentang kompatibilitas kode objek. OP membeli kode sumber .
Lightness Races dengan Monica

7
@LightnessRacesinOrbit Pertanyaannya berbicara tentang menggunakan kompiler yang berbeda untuk menghasilkan satu executable. Bukan lompatan besar untuk berpikir, "Mereka berarti mengkompilasi kode pihak ketiga dengan satu kompiler (mungkin yang 'didukung') dan kode mereka sendiri dengan kompiler yang berbeda (mungkin yang lebih baru)." (Ini jelas yang saya pahami OP ingin ditanyakan; jika Anda membacanya secara berbeda, Anda mungkin ingin meminta OP untuk mengklarifikasi.) Dalam kemungkinan itu atau yang serupa lainnya, kompatibilitas kode objek tampaknya sangat relevan.
jpmc26

1
@ jpmc26: "Ini jelas yang saya pahami OP ingin tanyakan; jika Anda membacanya secara berbeda, Anda mungkin ingin meminta OP untuk mengklarifikasi." OP dengan jelas menyatakan bahwa perusahaan mereka "akan membeli sepotong kode sumber yang besar dan sangat kompleks". Lebih jauh lagi, dengan pernyataan seperti "dapat dibayangkan bahwa versi berbeda dari kompiler akan menghasilkan kode objek yang berbeda, yang berpotensi mengarah pada perbedaan waktu", mereka bertanya tentang perubahan apa ketika mereka mengkompilasi kode yang dibeli dengan alat bantu yang berbeda, bukan hanya milik mereka. Saya tidak berpikir ada banyak ruang untuk interpretasi di sana!
Lightness Races dengan Monica

8

Apakah kita perlu menggunakan kompiler yang sama dan versi kompiler yang sama seperti yang digunakan untuk mengembangkan kode yang dibeli? Apakah kita perlu menggunakan versi C ++ yang sama dengan kode yang dibeli?

Ini bukan pertanyaan teknis. Ini adalah pertanyaan hukum tentang apa yang Anda tulis dalam kontrak Anda. Pastikan vendor perangkat lunak memberi Anda versi yang dijamin olehnya untuk dapat digunakan di lingkungan Anda. Jika tidak, akan selalu ada risiko tertentu untuk mengalami masalah dengan kompiler, versi kompiler, atau versi bahasa yang berbeda.

Ini sangat penting ketika Anda membeli komponen atau bagian-bagian itu sebagai sumber tertutup. Bahkan jika pemasok Anda menjamin Anda dapat menggunakan komponen dengan lingkungan kompiler Anda saat ini, apakah dia menjamin dia akan memberi Anda pembaruan jika Anda ingin beralih ke versi kompiler yang lebih baru di masa depan? Jika Anda tidak memiliki akses ke kode sumber lengkap, Anda mungkin tidak akan beruntung mencoba menyelesaikan masalah kompatibilitas sendiri. Itu sebabnya Anda tidak hanya harus membeli perangkat lunak, tetapi juga memikirkan kontrak perawatan jangka panjang dengan pemasok Anda.


Ini sebenarnya saran yang cukup bagus!
T. Sar - Reinstate Monica

Memang, tapi sayang sekali sudah terlambat. Ketika saya berkomentar atas komentar Basile, saya juga menanyakan pertanyaan pemasok ini. Tapi saya pikir itu akan menjadi titik diskusi yang baik di sini, dan referensi masa depan yang baik untuk orang lain di masa depan
Mawg mengatakan mengembalikan Monica

4

Perusahaan kami akan membeli sepotong kode sumber yang besar dan sangat kompleks untuk komunikasi satelit. Ini dikodekan dalam C ++ dan kami akan menambahkan kode untuk itu, juga di C ++, menghubungkan kode kami dengan kode yang dibeli ke dalam satu unit yang dapat dieksekusi.

Kedengarannya bagus!

Apakah kita perlu menggunakan kompiler yang sama dan versi kompiler yang sama seperti yang digunakan untuk mengembangkan kode yang dibeli?

Berbicara secara umum, tidak, itu tidak perlu. Tujuan dari C ++ adalah untuk bertindak sebagai abstraksi atas hal-hal ini, sehingga program C ++ yang ditulis dengan baik akan mengkompilasi dengan baik pada toolchain Anda seperti yang dilakukan pada pembuat asli, dan program yang dihasilkan akan memiliki hasil yang sama. Kinerja dapat bervariasi, karena kompiler yang berbeda pandai dalam hal yang berbeda, tetapi perilaku dasar program tidak boleh berubah.

Namun, perangkat lunak yang ditulis dengan buruk dapat mengandalkan perilaku khusus implementasi, atau bahkan perilaku yang tidak terdefinisi. Ini dapat membuat asumsi tentang tipe bawaan, atau tentang endianness platform. Bahkan perangkat lunak yang ditulis dengan baik mungkin tidak memiliki pilihan selain mengandalkan ekstensi non-standar yang tidak tersedia pada rantai alat yang Anda pilih, atau mungkin melakukannya karena tidak perlu menghabiskan waktu untuk menambahkan lapisan portabilitas dalam durasi proyek asli.

Pada akhirnya, Anda harus bertanya kepada pembuat / vendor untuk apa kode sumber ditulis. Jika mereka mengklaim bahwa itu secara khusus menentang, katakanlah, Visual Studio 2015, dan memerlukan fitur Windows API, Anda mungkin harus tetap menggunakannya. Tetapi jika mereka mengklaim itu portabel, standar C ++, maka gunakan kompiler apa pun yang Anda suka. Pastikan perjanjian pembelian Anda menyertakan pengaturan dukungan sehingga Anda bisa mendapatkan bantuan gratis saat ternyata vendor berbohong.

Apakah kita perlu menggunakan versi C ++ yang sama dengan kode yang dibeli? Jika tidak menggunakan 2014, kami mungkin ingin menggunakan beberapa fitur itu, tetapi tidak jika mungkin ada beberapa masalah dengan pencampuran versi yang berbeda.

Mungkin. Mungkin.

C ++ 03 kompatibel ke depan untuk sebagian besar, jadi, jika kodenya C ++ 03, maka Anda tidak akan mengalami masalah. (Meskipun beberapa tweak mungkin diperlukan.)

Tetapi fitur-fitur yang diperkenalkan dalam C ++ 11 dan C ++ 14 tidak kompatibel-mundur jadi jika vendor menggunakan, katakanlah, C ++ 11 lambdas, dan Anda mencoba untuk membangun kode mereka dalam kompiler C ++ 03, yang baru saja memenangkan bekerja.

Secara teori, tentu saja, seharusnya tidak menjadi masalah, terutama versi bahasa, tetapi dapat dibayangkan bahwa versi berbeda dari kompiler akan menghasilkan kode objek yang berbeda, yang berpotensi mengarah pada perbedaan waktu, dll.

Benar. Jika kode sangat bergantung pada implementasi spesifik untuk mendapatkan hasil yang diharapkan, maka tergantung pada vendor untuk bertanggung jawab dan memberi tahu Anda mengenai hal itu. Karena kita hidup di dunia nyata, saya sarankan untuk rajin dan bertanya kepada mereka terlebih dahulu.

Dan saya akan menggemakan apa yang dikatakan orang lain: memastikan bahwa Anda memiliki semacam dukungan bantuan, sehingga jika mereka salah mengartikan salah satu dari respons terhadap pertanyaan-pertanyaan ini (baik sengaja atau tidak), Anda tidak akhirnya memikul biaya yang dihasilkan.


Patut dicatat: penautan tidak sepenuhnya tercakup dalam spesifikasi C ++. Meskipun kode dapat dikompilasi dalam beberapa kompiler yang sesuai, itu tidak dijamin bahwa Anda hanya dapat menautkannya bersama dan membuatnya bekerja.
Cort Ammon - Reinstate Monica

1
@CortAmmon: Anda harus / harus mengkompilasi semua komponen dari distribusi yang dihasilkan dengan toolchains yang berbagi ABI. Standar ABI berada di luar cakupan C ++. Saya tidak berpikir OP bertanya tentang pencampuran toolchains.
Lightness Races dengan Monica

2

Anda tidak menautkan kode, Anda menautkan file objek yang dikompilasi.

Dalam hal ini ya, menggunakan kompiler C ++ yang berbeda (atau bahkan pengaturan seperti debug / rilis build), atau versi yang berbeda, atau pustaka standar yang berbeda (versi) ketika membangun bagian yang akan berinteraksi pada tingkat biner sangat mungkin untuk memecahkan aplikasi jika bagian berkomunikasi satu sama lain menggunakan lebih dari C API.

Fitur seperti wadah atau pengecualian menyediakan antarmuka yang sama tetapi, pada tingkat biner, dapat diimplementasikan dalam banyak cara berbeda yang tidak kompatibel.

Namun, menggunakan kompiler yang berbeda untuk mengkompilasi seluruh kode adalah masalah yang berbeda. Pertanyaan untuk dipertimbangkan:

  • Platform / arsitektur apa yang menjadi target kode?
  • Untuk standar apa itu ditulis?
  • Apakah ia menggunakan fitur kompiler non-standar?
  • Apakah kode mengandung asumsi spesifik platform hard-coded (seperti selalu mempertimbangkan bahwa pointer menempati 2 byte)?

Ada juga risiko bahwa kode dapat berisi bagian-bagian yang mengakibatkan perilaku tidak terdefinisi. Ini bisa berfungsi dengan baik ketika menggunakan satu kompiler tetapi gagal dengan cara yang misterius ketika menggunakan yang lain.


OP sedang membangun kode, bukan vendor. OP bertanya bagaimana mengubah lingkungan build (lih. Vendor) dapat memengaruhi pembuatan kode dengan basis kode yang sama.
Lightness Races dengan Monica

1

Apakah kita perlu menggunakan kompiler yang sama dan versi kompiler yang sama seperti yang digunakan untuk mengembangkan kode yang dibeli?

Nah, beralih kompiler, dapat menyebabkan beberapa masalah; Saat ini di perusahaan saya, kami menggunakan Dentang dan MSVC, dan kami memiliki kesalahan dalam satu kompiler yang tidak ditandai oleh yang lain.

Apakah kita perlu menggunakan versi C ++ yang sama dengan kode yang dibeli? Jika tidak menggunakan 2014, kami mungkin ingin menggunakan beberapa fitur itu, tetapi tidak jika mungkin ada beberapa masalah dengan pencampuran versi yang berbeda.

Itu tidak perlu, tetapi tentu saja Anda kompiler harus mendukung versi C ++ yang ingin Anda gunakan. C ++ menjamin kompatibilitas retro mulai dari semua versi.


Cukup banyak pemikiran saya. Bagaimana dengan versi kompiler - jika mereka menggunakan GCC versi x dan yang terbaru adalah x + 2, misalnya?
Mawg mengatakan mengembalikan Monica

1
Nah, jika mereka menggunakan versi kompiler yang lebih lama yang ingin Anda gunakan, tidak ada masalah, karena tidak ada yang namanya barang usang, masalahnya bisa naik jika mereka menggunakan versi kompiler Anda yang lebih baru.
LaboPie

Tapi bagaimana caranya? Saya juga akan memilih untuk tidak. Tetapi apakah Anda mengetahui adanya jenis masalah yang dapat terjadi?
Mawg mengatakan mengembalikan Monica

Tetapi apakah Anda mengetahui adanya jenis masalah yang dapat terjadi? Jika mereka menggunakan beberapa fungsi yang tidak didukung oleh kompiler kami, kode tidak akan dikompilasi.
LaboPie

1
Sedikit lampiran, tentu saja masalahnya menjadi lebih besar jika kompiler yang digunakan dari kantor lain bukan yang utama. EG kompiler konsol lama, atau sesuatu yang berfungsi dengan subset bahasa.
LaboPie

1

Satu masalah besar ketika mengganti kompiler adalah perilaku yang tidak terdefinisi: Jika kode yang Anda terima memanggil perilaku yang tidak terdefinisi, maka segala sesuatu mungkin terjadi - termasuk bahwa kode tersebut berfungsi dengan baik dan melewati semua pengujian saat menggunakan kompiler, dan sangat salah dengan kompiler Anda.

Itu mungkin, tetapi dalam situasi itu Anda mungkin juga mengalami masalah jika Anda mengubah level optimisasi, gunakan versi berikutnya dari kompiler yang sama dan seterusnya. Jadi tidak ada yang bisa Anda hindari.


Ini adalah argumen yang bagus untuk menggunakan lint dan mungkin valgrind .
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.