Salah satu keluhan utama saya tentang C ++ adalah seberapa sulit dalam praktiknya untuk melewati objek perpustakaan std di luar perpustakaan dinamis (yaitu dll / jadi) batas.
Perpustakaan std sering hanya header-saja. Yang bagus untuk melakukan beberapa optimasi yang luar biasa. Namun, untuk dll, mereka sering dibangun dengan pengaturan kompiler berbeda yang dapat berdampak pada struktur internal / kode wadah perpustakaan std. Sebagai contoh, di MSVC satu dll dapat dibangun dengan iterator debugging sementara yang lain membangun dengan itu. Kedua dll ini mungkin mengalami masalah ketika melewati wadah std. Jika saya mengekspos std::string
di antarmuka saya, saya tidak dapat menjamin kode yang digunakan klien adalah std::string
cocok dengan perpustakaan saya std::string
.
Hal ini menyebabkan sulitnya men-debug masalah, sakit kepala, dll. Anda dapat secara kaku mengontrol pengaturan kompiler di organisasi Anda untuk mencegah masalah ini atau Anda menggunakan antarmuka C sederhana yang tidak akan memiliki masalah ini. Atau tentukan kepada klien Anda pengaturan kompiler yang diharapkan yang harus mereka gunakan (yang menyebalkan jika perpustakaan lain menentukan pengaturan kompiler lain).
Pertanyaan saya adalah apakah C ++ 11 mencoba melakukan sesuatu untuk menyelesaikan masalah ini?
DLL
s. AntaraSO
itu selalu bekerja dengan baik.Jawaban:
Anda benar bahwa apa pun STL - sebenarnya, apa pun dari pustaka pihak ketiga mana pun yang templated - sebaiknya dihindari di sembarang API C ++ publik. Anda juga ingin mengikuti daftar panjang aturan di http://www.ros.org/reps/rep-0009.html#definition untuk menghambat kerusakan ABI yang menjadikan pemrograman publik C ++ API menjadi tugas.
Dan jawaban tentang C ++ 11 adalah tidak, standar ini tidak menyentuh itu. Lebih menarik kenapa tidak? Jawabannya adalah karena C ++ 17 sangat menyentuh itu, dan untuk C ++ Modul yang akan dilaksanakan kita perlu template yang diekspor untuk bekerja, dan untuk itu kita memerlukan kompiler tipe LLVM seperti dentang yang dapat membuang AST penuh ke disk dan kemudian lakukan pencarian tergantung-penelepon untuk menangani banyak kasus pelanggaran ODR di setiap proyek C ++ besar - yang, omong-omong, mencakup banyak kode GCC dan ELF.
Terakhir, saya melihat banyak kebencian MSVC dan komentar pro-GCC. Ini sangat salah informasi - GCC pada ELF pada dasarnya, dan tidak dapat diperbaiki lagi, tidak mampu menghasilkan kode C ++ yang valid dan benar. Alasannya banyak dan banyak, tetapi saya akan dengan cepat mengutip satu contoh kasus: GCC pada ELF tidak dapat dengan aman menghasilkan ekstensi Python yang ditulis menggunakan Boost.Python di mana lebih dari satu ekstensi berdasarkan Boost.Python dimuat ke Python. Itu karena ELF dengan tabel simbol C globalnya tidak mampu untuk mencegah pelanggaran ODR yang menyebabkan segfault, sedangkan PE dan MachO dan spesifikasi Modul C ++ yang diusulkan semuanya menggunakan tabel simbol per-modul - yang notabene juga berarti proses yang jauh lebih cepat di kali. Dan ada banyak masalah lagi: lihat StackOverflow saya jawab baru-baru ini dihttps://stackoverflow.com/questions/14268736/symbol-visibility-exceptions-runtime-error/14364055#14364055 misalnya di mana lemparan pengecualian C ++ secara fundamental diperbaiki pada ELF.
Poin terakhir: mengenai interoping berbagai STL, ini adalah rasa sakit yang besar bagi banyak pengguna perusahaan besar yang mencoba untuk menggabungkan perpustakaan pihak ketiga yang terintegrasi erat dengan beberapa implementasi STL. Satu-satunya solusi adalah mekanisme baru untuk C ++ untuk menangani STL interop, dan sementara mereka berada di sana Anda mungkin juga memperbaiki kompiler interop juga sehingga Anda dapat (misalnya) mencampur file objek yang dikompilasi MSVC, GCC dan dentang dan semuanya hanya berfungsi . Saya akan menonton upaya C ++ 17 dan melihat apa yang muncul di sana dalam beberapa tahun mendatang - saya akan terkejut jika tidak ada yang berhasil.
sumber
Spesifikasi tidak pernah memiliki masalah ini. Itu karena ia memiliki konsep yang disebut "aturan satu definisi", yang mengamanatkan bahwa setiap simbol memiliki tepat satu definisi dalam proses yang sedang berjalan.
Windows DLL melanggar persyaratan ini. Itu sebabnya ada semua masalah ini. Jadi terserah Microsoft untuk memperbaikinya, bukan komite standardisasi C ++. Unix tidak pernah memiliki masalah ini, karena pustaka bersama bekerja secara berbeda di sana dan secara default sesuai dengan satu aturan definisi (Anda dapat secara eksplisit melanggarnya, tetapi Anda jelas hanya melakukannya jika Anda tahu Anda mampu dan perlu memeras beberapa siklus tambahan).
Windows DLL melanggar satu aturan definisi karena:
Unix menggunakan ekspor format ELF secara implisit mengimpor semua simbol yang diekspor untuk menghindari masalah pertama dan tidak membedakan antara simbol yang diselesaikan secara statis dan dinamis hingga waktu tautan statis untuk menghindari yang kedua.
Masalah lainnya adalah flag compiler. Masalah itu ada untuk setiap program yang terdiri dari beberapa unit kompilasi, pustaka dinamis tidak harus terlibat. Namun itu jauh lebih buruk di Windows. Di Unix tidak masalah apakah Anda menautkan secara statis atau dinamis, tidak ada yang menautkan runtime standar secara statis (di Linux bahkan mungkin ilegal) dan tidak ada runtime debug khusus, sehingga satu build cukup bagus. Tetapi cara Microsoft menerapkan penghubung statis dan dinamis, debug, dan pelepasan runtime dan beberapa opsi lain berarti mereka menyebabkan ledakan kombinasi varian perpustakaan yang diperlukan. Sekali lagi masalah platform daripada masalah bahasa C ++.
sumber
Tidak.
Ada banyak pekerjaan yang terjadi untuk mengganti sistem header, fitur yang disebut Modul dan yang dapat berdampak pada hal ini, tetapi tentu saja bukan yang besar.
sumber