Saya baru-baru ini bertanya-tanya kapan harus menggunakan C lebih dari C ++, dan sebaliknya? Untungnya seseorang sudah mengalahkan saya untuk itu dan meskipun butuh beberapa saat, saya bisa mencerna semua jawaban dan komentar untuk pertanyaan itu.
Namun satu item dalam posting itu terus ditangani berulang kali, tanpa ada contoh, verifikasi atau penjelasan:
"Kode C baik untuk ketika Anda ingin memiliki beberapa ikatan bahasa untuk perpustakaan Anda"
Itu parafrase. Saya harus mencatat bahwa beberapa orang menunjukkan bahwa binding beberapa bahasa dimungkinkan dalam C ++ (melalui beberapa extern
fungsi), namun demikian, jika Anda membaca posting itu secara keseluruhan, cukup jelas bahwa C sangat ideal untuk portabilitas / pengikatan bahasa. Pertanyaan saya adalah: mengapa?
Dapatkah seseorang tolong memberikan alasan konkret mengapa menulis perpustakaan di C memungkinkan untuk binding dan / atau portabilitas yang lebih mudah dalam bahasa lain?
Jawaban:
C memiliki antarmuka yang jauh lebih sederhana, dan aturannya untuk mengubah antarmuka kode sumber menjadi antarmuka biner cukup mudah sehingga menghasilkan antarmuka eksternal untuk diikat dilakukan dengan cara yang mapan. C ++, di sisi lain, memiliki antarmuka yang sangat rumit, dan aturan untuk pengikatan ABI sama sekali tidak standar, baik secara formal maupun dalam praktik. Ini berarti bahwa hampir semua kompiler untuk bahasa apa pun untuk platform apa pun dapat mengikat antarmuka C eksternal dan tahu persis apa yang diharapkan, tetapi untuk antarmuka C ++, itu pada dasarnya tidak mungkin karena peraturan berubah tergantung pada kompiler mana, versi mana, dan yang mana Platform kode C ++ dibuat.
sumber
extern "C"
, masih banyak pekerjaan tambahan untuk melakukannya, yang harus diseimbangkan dengan fitur-fitur yang disediakan oleh C ++)extern "C"
.Jika Anda mencoba berkomunikasi dengan penutur bahasa lain, pidgin lebih mudah daripada bahasa Inggris Shakespeare.
Konsep C - panggilan fungsi, pointer, string yang diakhiri NULL - sangat mudah, sehingga bahasa lain dapat dengan mudah mengimplementasikannya dengan cukup baik untuk memanggil fungsi C. Karena alasan historis, banyak bahasa lain diimplementasikan dalam C, yang membuat pemanggilan fungsi C lebih mudah.
C ++ menambahkan sedikit hal - kelas, dengan warisan dan vtables dan pengubah akses; pengecualian, dengan tumpukan membuka dan mengubah aliran kontrol; template. Semua ini mempersulit bahasa lain untuk menggunakan binding C ++: paling-paling, ada lebih banyak "lem" atau kode interoperabilitas untuk diimplementasikan, dan paling buruk, konsep tidak diterjemahkan secara langsung (karena perbedaan dalam model kelas, penanganan pengecualian, dll.) Untuk template khususnya, cukup menggunakan (instantiating) mereka biasanya memerlukan langkah kompilasi dengan kompiler C ++, yang sangat menyulitkan menggunakannya dari lingkungan lain.
Dengan semua itu, mungkin untuk melebih-lebihkan kesulitan menyediakan binding dari pustaka C ++ ke bahasa lain:
extern "C"
, sehingga Anda dapat mengekspor binding bahasa gaya-C (dengan semua kesederhanaan dan kompatibilitas binding C) dari pustaka C ++ (dengan batasan bahwa Anda tidak dapat mengekspos C ++ - fungsionalitas khusus) .sumber
C adalah salah satu bahasa tertua yang masih ada. ABI-nya sederhana, dan hampir setiap sistem operasi yang masih digunakan saat ini telah ditulis di dalamnya . Sementara beberapa OS tersebut mungkin telah menambahkan hal-hal misalnya dalam C # /. NET atau apa pun di atas, di bawah mereka sangat mendalami C.
Itu berarti bahwa, untuk menggunakan fungsionalitas yang disediakan oleh OS, hampir setiap bahasa pemrograman di luar sana membutuhkan cara untuk berinteraksi dengan C perpustakaan pula . Perl, Java, C ++, mereka semua secara native menyediakan cara untuk "berbicara C", karena mereka harus jika mereka tidak ingin menemukan kembali setiap roda yang ada.
Ini menjadikan C bahasa Latin dari bahasa pemrograman. (Berapa tahun internet sebelum metafora itu harus menjadi "bahasa Inggris untuk bahasa pemrograman"?)
Saat Anda menulis pustaka di C, Anda mendapatkan antarmuka yang kompatibel dengan C secara gratis (jelas). Jika Anda menulis perpustakaan Anda di C ++, Anda bisa mendapatkan binding C, melalui
extern "C"
deklarasi seperti yang Anda sebutkan.Namun , Anda bisa mendapatkan orang-binding hanya untuk fungsi yang dapat dinyatakan dalam C .
Jadi API perpustakaan Anda tidak dapat menggunakan ...
Salah satu contoh sederhana, Anda perlu membuat fungsi yang diekspor mengambil dan mengembalikan array (
[]
) alih-alihstd::vector
(ataustd::string
dalam hal ini).Jadi, tidak hanya Anda tidak dapat memberikan hal-hal baik yang ditawarkan C ++ kepada klien perpustakaan Anda, Anda juga harus melakukan upaya tambahan untuk "menerjemahkan" API perpustakaan Anda dari C ++ ke "C kompatibel" (
extern "C"
).Itulah mengapa poin dapat dibuat bahwa C adalah pilihan yang lebih baik untuk mengimplementasikan perpustakaan. Secara pribadi, saya pikir manfaat C ++ masih lebih besar daripada upaya yang diperlukan untuk
extern "C"
API, tapi itu hanya saya.sumber
Meninggalkan detail jawaban lain sudah memberikan:
Alasan mengapa begitu banyak bahasa menyediakan ikatan C adalah karena semua * nix dan sistem operasi Windows memaparkan sebagian besar API OS mereka melalui antarmuka C. Jadi implementasi bahasa sudah perlu antarmuka dengan C untuk dapat berjalan pada Oses utama. Oleh karena itu, sangat mudah untuk juga menawarkan komunikasi langsung dengan antarmuka C dari bahasa itu sendiri.
sumber
Tidak ada alasan. Jika semantik yang ingin Anda ekspresikan pada dasarnya kompatibel dengan C dan bukan sesuatu seperti templat, tidak ada alasan Anda dapat mengikat lebih mudah jika implementasinya ditulis dalam C. Sebenarnya, cukup banyak definisi bahwa antarmuka C dapat diisi oleh implementasi apa pun yang dapat memenuhi kontrak biner - termasuk implementasi dalam bahasa lain. Ada bahasa selain C ++ yang dapat mengimplementasikan kontrak biner C yang dapat bekerja dengan cara ini.
Apa yang sebenarnya menjadi intinya adalah orang-orang yang tidak ingin belajar bahasa atau ide-ide baru yang sebenarnya memiliki semantik atau fitur yang mati-matian berusaha untuk mengambil alasan untuk tetap berada di era dinosaurus.
sumber
Ada dua sumbu utama saat berinteraksi dengan bahasa lain:
C memiliki keunggulan dibandingkan C ++ di kedua bidang tersebut:
Sekarang, mengapa sebagian besar bahasa memiliki seperangkat konsep yang sama daripada C mungkin karena itu baik "sederhana" atau "sudah ada"; tidak masalah, intinya mereka melakukannya.
Sebaliknya, C ++ memiliki konsep yang kompleks, dan ABI ditentukan oleh masing-masing kompiler (meskipun banyak yang mematuhi ABI Itanimum, kecuali pada Windows ...). Sebenarnya ada proposal oleh Herb Sutter untuk meminta OS memperbaiki C ++ ABI (berdasarkan per OS) untuk mengatasi sebagian masalah ini. Juga, orang harus mencatat bahwa C ++ FFI adalah mungkin, D sedang mencobanya 3 .
1 Kecuali variadics (
...
), itu tidak sederhana2 Apakah C memiliki ABI standar?
3 Menghubungkan kode D ke Legacy C ++
sumber
Pada dasarnya itu turun ke standardisasi ABI. Sementara C atau C ++ tidak memiliki ABI standar yang dapat digunakan bahasa lain untuk antarmuka antara biner yang ditulis, C telah menjadi standar de-facto, semua orang tahu dan semua orang dapat menggunakan aturan yang sama, sederhana, yang dimiliki bahasa sehubungan dengan jenis dan panggilan fungsi.
C ++ dapat memiliki ABI standar, tetapi Stroustrup mengatakan bahwa ia tidak melihat perlunya ABI. Dia juga mengatakan akan sulit untuk mendapatkan konsensus dari penulis kompiler (meskipun saya ragu bahwa - komite standar C ++ akan mengeluarkan ABI yang mirip dengan yang ada dan penulis kompiler hanya akan mengubah versi berikutnya dari kompiler mereka, yang kadang-kadang tidak kompatibel dengan biner. dibangun dengan versi lama kompiler mereka - saya ingat mengkompilasi ulang beberapa perpustakaan dengan kompiler Sun baru dan menemukan mereka gagal bekerja dengan yang lama)
Anda akan mencatat bahwa beberapa perusahaan telah pindah ke menggunakan ABI standar, Microsoft memulai proses ini dengan cara COM kembali di tahun 90-an, dan hari ini mereka telah menyempurnakan ini menjadi WinRT ABI (jangan bingung dengan WinRT lain yang merujuk ke jenis tabel OS) yang memungkinkan program yang ditulis dalam C # untuk berkomunikasi dengan perpustakaan yang ditulis dalam C atau C ++ (yaitu lapisan OS Microsoft sendiri ditulis dalam C ++, diekspos menggunakan WinRT dan dikonsumsi oleh aplikasi C # ketika mereka memanggil rutin runtime OS)
Tidak banyak yang bisa dilakukan orang kecuali badan standar meningkatkan dan memperbaiki situasi ini. Microsoft jelas melihat nilai di dalamnya dan telah mengambil langkah-langkah untuk menyelesaikannya untuk platform mereka.
Jadi jawabannya benar-benar C tidak memberikan ikatan bahasa. Itu terjadi bahwa tidak ada yang mendengarkan dan mengkonsumsinya terlepas.
sumber
Semua jawaban gagal dari masalah sebenarnya: kompilasi C ++ memperkenalkan "name mangling", sehingga biner tidak kompatibel dengan pemanggilan fungsi "sederhana".
Semua hal ABI lebih dari sekadar upaya untuk membakukannya.
Secara umum itu tidak dijamin Anda dapat cross-link fungsi dikompilasi dengan kompiler yang berbeda, bahkan jika Anda tetap menggunakan C ++. Sebelumnya yakin mereka tidak kompatibel, tetapi saat ini standardisasi merayap masuk;)
OTOH C dirancang dengan tepat untuk menjadi "Majelis tingkat tinggi" dan memungkinkan semua jenis antarmuka yang mudah. Seharusnya tidak mengejutkan itu lebih cocok untuk menyukai lintas bahasa.
Catatan: kompiler C ++ asli (cfront) sebenarnya menghasilkan sumber C yang harus dikompilasi, persis seperti gcc yang menghasilkan Majelis "di bawah tenda".
sumber