Saya mengerti bahwa kompiler C ++ tidak kompatibel satu sama lain. Namun, saya tidak dapat menemukan apapun tentang topik ini untuk C khususnya. Saya tahu bahwa standar C menyisakan banyak ruang bagi kompiler untuk mengimplementasikan hal-hal yang mereka anggap cocok: misalnya, ukuran dan penyelarasan sebagian besar (semua?) Tipe data ditentukan oleh implementasi, hemat untuk beberapa jaminan minimal. Oleh karena itu, dua kompiler (atau dua versi dari kompiler yang sama) dapat tidak setuju pada banyak detail.
Apakah saya benar dalam berpikir bahwa tidak ada jaminan bahwa dua file objek yang dikompilasi dengan kompiler yang berbeda akan terhubung dengan benar? Misalnya, ukuran pointer bisa 32 bit di satu file objek dan 64 bit di yang lain. Tetapi jika demikian, mengapa perpustakaan C kadang-kadang didistribusikan dalam bentuk yang dikompilasi? Apakah ada harapan bahwa saya akan menggunakan kompiler yang sama seperti yang mereka lakukan (misalnya gcc), atau standar de facto yang digunakan untuk memastikan kompatibilitas biner? Dan bagaimana bahasa lain dengan Antarmuka Bahasa Asing memastikan hal-hal akan berbaris dengan benar ketika menghubungkan dengan file objek C?
Jawaban:
Jawaban umum adalah tidak, kompiler bahasa C tidak kompatibel satu sama lain. Standar bahasa C tidak mendefinisikan interoperabilitas biner apa pun, dan sebagian besar penulis kompiler bahkan tidak mencoba.
Saya harus memenuhi syarat itu. Objek yang dipancarkan oleh kompiler C harus dihubungkan dengan pustaka runtime untuk menghasilkan pustaka yang dapat dieksekusi atau runtime yang dapat ditautkan. Meskipun fungsi yang terlihat yang disediakan oleh pustaka runtime C harus kompatibel, akan ada juga fungsi yang tidak terlihat yang unik untuk implementasi dan mencegah interoperabilitas.
Kurangnya kompatibilitas ini juga meluas ke versi berbeda dari kompiler yang sama. Secara umum, program dan pustaka yang dikompilasi dengan versi kompiler yang lebih lama dan lebih baru tidak dapat dihubungkan bersamaan, dan yang dikompilasi dengan MSVC tidak dapat dihubungkan dengan yang dikompilasi oleh GCC.
Ada pengecualian khusus dan sangat berguna. Setiap platform menyediakan ABI penghubung dinamis (Application Binary Interface) dan program apa pun dalam bahasa apa pun yang dapat sesuai dengan ABI yang kompatibel. Oleh karena itu secara umum dimungkinkan untuk membangun DLL (di Windows) dengan MSVC (atau yang lainnya) dan menyebutnya dari program yang dikompilasi oleh versi MSVC yang berbeda atau oleh GCC dan sebaliknya.
Ada dua ABI lain di Windows: COM dan .NET assemblies, dan mereka menjangkau berbagai bahasa. Jadi interoperabilitas jelas dimungkinkan, tetapi tidak kompatibel.
Tingkat ketidakcocokan dapat dengan mudah dilihat dengan membandingkan peta tautan. Untuk penggunaan GNU
ld -M
, untuk penggunaan MSVClink /map
. Pelajari dua file yang dihasilkan. Keduanya akan memiliki nama-nama di dalamnya yang Anda kenali, seperti printf dan main, meskipun (tergantung pada opsi) nama-nama tersebut kemungkinan akan hancur dalam berbagai cara. Mereka juga akan memiliki nama yang sama sekali berbeda, yang banyak di antaranya tidak akan Anda kenali. Agar file objek yang dihasilkan oleh kompiler berbeda agar kompatibel, mereka harus menyetujui semua nama itu, dan mereka tidak pernah melakukannya. Bahkan versi berbeda dari kompiler yang sama selalu dapat melakukan itu.sumber
Apa yang Anda cari di disebut ABI (Application Binary Interface).
Bahasa C tidak mendefinisikan ABI, jadi dalam hal itu memang tidak ada jaminan bahwa file C yang dikompilasi dengan kompiler yang berbeda akan bekerja satu sama lain.
Di sisi lain, pada kebanyakan platform OS mendefinisikan ABI untuk berinteraksi dengannya dan semua kompiler yang menargetkan keluarga prosesor & OS juga menggunakan ABI yang sama untuk berinteraksi dengan komponen non-OS. Jadi, dalam praktiknya, objek C yang dibuat oleh kompiler yang berbeda dapat bekerja satu sama lain.
sumber