Farklı derleyicilerle (C) nesne dosyaları ikili olarak uyumlu mudur?


11

C ++ derleyicilerinin birbiriyle uyumlu olmadığını anlıyorum. Ancak, özellikle C için bu konuda hiçbir şey bulamadım. C standardının, derleyicilerin uygun gördükleri şeyleri uygulaması için çok yer bıraktığını biliyorum: örneğin, çoğu (tüm?) Veri türlerinin boyutu ve hizalaması, bazı minimum garantiler için uygulama tanımlı bir tasarruftur. Bu nedenle, iki derleyici (veya aynı derleyicinin iki sürümü) birçok ayrıntıya katılmayabilir.

Farklı derleyicilerle derlenen iki nesne dosyasının gerçekten doğru şekilde bağlanacağının garantisi olmadığını düşünerek haklı mıyım? Örneğin, işaretçilerin boyutu bir nesne dosyasında 32 bit, diğerinde 64 bit olabilir. Ama eğer öyleyse, neden C kütüphaneleri bazen önceden derlenmiş biçimde dağıtılır? Yaptıkları aynı derleyiciyi (örn. Gcc) kullanacağım veya ikili uyumluluğu sağlamak için kullanılan fiili bir standart var mı? Yabancı Dil Arabirimine sahip diğer diller, C nesne dosyalarıyla bağlantı kurarken her şeyin düzgün bir şekilde hizalanmasını nasıl sağlar?


Hatırlayabildiğim kadarıyla, C nesne dosyaları aynı platform için derlendikleri sürece birbirleriyle uyumlu olmalıdır. Bir nesne dosyası, modül içindeki her sembole erişmek için kullanılabilecek bazı sembol tablosuna sahip yüklenebilir ikili kod içeren bir arşivdir.
Giorgio

2
libs uyumlu hale getirilebilir, obj'in olması garantili olduğunu sanmıyorum
cırcır ucube

@Giorgo "Aynı platform" ile CPU mimarisi veya CPU mimarisi + işletim sistemi mi demek istersiniz?
Doval

@ratchetfreak Ben bir lib çoğunlukla birden fazla nesne dosyalarının birleştirme olduğu izlenimi altındaydı. Yanlış mı?
Doval

Nesnelerin farklı derleyiciler arasında uyumlu olmasını beklemem.
old_timer

Yanıtlar:


10

Genel cevap hayır, C dil derleyicileri birbiriyle uyumlu değil. C dili standardı herhangi bir ikili birlikte çalışabilirlik tanımlamaz ve çoğu derleyici yazarı bile denemez.

Bunu kabul etmeliyim. Bir C derleyicisi tarafından yayılan nesnelerin, yürütülebilir veya çalışma zamanı ile bağlanabilir bir kitaplık üretmek için çalışma zamanı kitaplıklarıyla bağlanması gerekir. C çalışma zamanı kitaplığı tarafından sağlanan görünür işlevler uyumlu olmakla birlikte, uygulamaya özgü ve birlikte çalışabilirliği önleyen görünür olmayan işlevler de olacaktır.

Bu uyumsuzluk aynı derleyicinin farklı sürümlerine de uzanır. Genel olarak, bir derleyicinin eski ve daha yeni sürümleriyle derlenen programlar ve kütüphaneler birbirine bağlanamaz ve MSVC ile derlenenler GCC tarafından derlenenlere bağlanamaz.

Özel ve çok kullanışlı bir istisna vardır. Her platform, dinamik bir bağlantı ABI (Uygulama İkili Arabirimi) ve bu ABI ile uyumlu olabilecek herhangi bir dilde herhangi bir program sağlar. Bu nedenle, MSVC (veya başka bir şey) ile bir DLL (Windows üzerinde) oluşturmak ve MSVC'nin farklı bir sürümü veya GCC tarafından derlenmiş bir programdan çağırmak genellikle mümkündür (veya tam tersi).

Windows'ta başka iki ABI daha vardır: COM ve .NET derlemeleri ve çok çeşitli dillere yayılmıştır. Bu nedenle birlikte çalışabilirlik kesinlikle mümkündür, ancak uyumlu değildirler.


Uyumsuzluk derecesi bağlayıcı haritaları karşılaştırılarak kolayca görülebilir. GNU kullanımı ld -Miçin, MSVC kullanımı için link /map. Oluşturulan iki dosyayı inceleyin. Her ikisinde de (seçeneklere bağlı olarak) adların çeşitli şekillerde yönetilmesi muhtemel olsa da, printf ve main gibi tanıdığınız adlar olacaktır. Ayrıca tamamen farklı olan, birçoğu tanımayacağınız isimlere sahip olacaklar. Farklı derleyiciler tarafından üretilen nesne dosyalarının uyumlu olması için tüm bu isimler üzerinde anlaşmaları gerekir ve asla kabul etmezler. Aynı derleyicinin farklı sürümleri bile her zaman bunu yapamaz.


Bu cevap çelişmektedir görünüyor Bart ; yalnızca paylaşılan kütüphanelerin uyumlu olduğu anlaşılıyor. C çalışma zamanı kitaplığının görünür olmayan, uygulamaya özgü işlevlerinin neden birlikte çalışabilirliği önlediğini açıklayabilir misiniz? Ayrıca, "C derleyicisi tarafından yayılan nesnelerin yürütülebilir veya çalışma zamanı ile bağlanabilir bir kitaplık oluşturmak için çalışma zamanı kitaplıklarıyla bağlantılı olması gerekir" diyorsunuz - ya statik kitaplıklar?
Doval

Bart'ın dediği gibi, yalnızca ABI olan kütüphaneler uyumludur. Paylaşılan kütüphaneler (Unix'te) bir çeşit ABI'dır, diğerleri vardır. HelloWorld.c yazın, MSVC ve gcc ile derleyin, haritaları karşılaştırın ve ne kadar farklı olduklarını göreceksiniz. 'Çalışma zamanı kitaplıkları', statik veya dinamik olarak bağlı olabilecek her C / C ++ derlemesinde otomatik olarak başvurulan temel destek işlevleri anlamına gelir. Görmek için haritayı veya CRT kaynak kodunu okuyun.
david.pfx

Haritaları karşılaştırmanın ne anlama geldiğini bilmiyorum, bu yüzden biraz daha spesifik olacağım: Uygulamada belirli bir CPU mimarisi ve OS kombinasyonu için tüm derleyicilerin uyumlu olduğunu varsaymak güvenli midir? Örneğin, ccc ile derlediğim gcc ve mylibrary.c ile derlediğim main.c, her ikisi de Linux x64'ü hedefliyor. Makul bir genel işletim sistemi (Linux, Mac, Windows) varsayarsak, iki derleyicinin ne olduğuna bakılmaksızın bunun işe yarayacağını düşünmek güvenli midir?
Doval

1
Son derece düşük bir olasılıkla, clang bağlantı haritasını kontrol edin. Bkz. Düzenleme.
david.pfx

17

Aradığınızda ABI (Uygulama İkili Arabirimi) denir.

C dili bir ABI tanımlamaz, bu nedenle farklı derleyicilerle derlenen C dosyalarının birbiriyle çalışacağının garantisi yoktur.

Öte yandan, çoğu platformda işletim sistemi onunla arabirim oluşturmak için bir ABI tanımlar ve işletim sistemi ve işlemci ailesinin işletim sistemi olmayan bileşenlerle arabirim için aynı ABI'yı kullanmasını hedefleyen tüm derleyiciler. Dolayısıyla, pratikte, farklı derleyiciler tarafından oluşturulan C nesneleri birbirleriyle çalışabilir.


Mantıklı. Paylaşılan kütüphaneleri işletim sisteminin ABI'sını da takip ediyorum?
Doval

3
@Doval Özellikle paylaşılan kütüphaneler, dış dünya tarafından çağrılabilir olmalıdır.
toasted_flakes
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.