2012-05-23 16 views
18

Ben ilke olarak bu muhtemelen tanımsız davranış olduğunu biliyoruz, ama büyük bir proje ile uğraşan çıkarına, burada GCC hakkında benim soru: Ben kullanarak, -std=c++11 ile tek transation gcc -std=c++98 ünitesi ve başka derlemek varsayalımFarklı GCC diyalektleri birbirine bağlanabilir mi?

tam aynı derleyici yüklemesi. İki nesne dosyasını bağlayabileceğim ve iyi tanımlanmış bir program alabileceğim herhangi bir garanti var mı?

Bildiğim kadarıyla, potansiyel problemler nedeniyle sadece farklı Makrolara kütüphane başlıkların farklı görünümler gelebilir ve bu da bu en iyi ihtimalle için, yeni üye işlevlerini, ama asla üye nesneleri eklersiniz söyleyebilirim standart kütüphane sınıfları.

Bu, büyük bir projenin farklı bölümlerini farklı dil lehçesi seçenekleri ile derlemek için kabul edilebilir mi?

Güncelleme: Eğer dik bir soru eklemek gerekir: Hangi iki farklı GCC sürümlerini (4.3 ve 4.6 diyelim ki) ancak kullanımı hakkında wht aynı lehçesi seçeneği (-std=c++98)? in this GCC documentation numaralı liste, kütüphanenin 4.2.2 ve 4.6 arasındaki her iki yönde uyumlu olduğunu akla getiriyor gibi görünüyor.

cevap

10

A priori, no. En güvenli çözüm, derleyici seçeneklerinin tümünün özdeş olduğunu varsaymaktır, derleyici özellikle bu seçeneğin ikili uyumluluğu etkilemediğini belgeler. (Çoğu derleyicide eksik olan belgeler). Uygulamada, belgelerin bulunmaması durumunda, uyarıları kontrol eden seçeneklerin (g ++ olarak -W...) ikili uyumluluğu etkilemeyeceği ve kod oluşumunu etkileyen bu seçeneklerin güvenli bir bahis olduğu görülmektedir (dil seviyesi, vb.): g ++, genel olarak VC++ gibi farklı seviyelerde optimizasyonlar arasında uyumluluk sağlar. Diğer bir önemli sorun ise komut satırındaki önişlemci sembollerini tanımlamaktır. Yine, en güvenli bahis, tüm tanımların aynı olması, aynı zamanda yine bazı sağduyuların sıralanmasıdır: projenizde kullanılan önişlemci sembolleri ile standart kütüphanenin derlenmesini beklemek zor olabilir (MYPROG_CONFIG_FILE_LOCATION, söylemek). Öte yandan, _GLIBCXX_DEBUG ve _GLIBCXX_DEBUG_PEDANTIC önişlemci tanımlarının ikili uyumluluğu etkileyeceğine dikkat edin (g ++, tutarlı bir şekilde kullanırsanız, onlarla çalışan bir kitaplık sürümü elde etmenizi sağlar). Sorunuzun ilgili olarak

: seçim kıracak şekilde, bazı önceden tanımlanmış önişlemci sembolleri etkiliyorsa nedeniyle pek beni şaşırtmaz standart versiyonunda, ama ikili uyumluluğu çok etkisi beklemiyorum kütüphanede ikili uyumluluk, _GLIBCXX_DEBUG ile bazı modülleri derlediyseniz ve bazıları olmadan. Çalışabilir, ama buna güvenmezdim.

+1

"tek güçlükle standart kütüphane projenizde kullanılan önişlemci sembolleri ile derlenmiş olan bekleyebilirsiniz" - ve öyle olsa bile, bir an makro için varsayalım:

Ayrıca ilgili bkz 'MYPROG_CONFIG_FILE_LOCATION' memset.c'de kullanılır, daha sonra 'memset.c' ifadesinin anlamı programınızdaki anlamıyla tamamen ilgisizdir. Bu yüzden eğer 'memset.c'' MYPROG_CONFIG_FILE_LOCATION' ile/olmadan 'ikili derleme için bir fark yaratırsa, programınızın' MYPROG_CONFIG_FILE_LOCATION' işlevini de kullanıp kullanmamasından bağımsız olarak bunu yapar. –

+0

@SteveJessop Evet. Olsa bile, size şeffaf olmalı. Pratikte, ad alanınızdaki tüm önişlemci sembolleri (yani, alt çizgi ile başlamıyor ve iki bitişik alt çizgi içermiyor) _should_ emin olun. Uygulama ismindeki önişlemci sembolleri, '_GLIBCXX_DEBUG' gibi olmayacak. –

3

Ben ilke olarak bu muhtemelen tanımsız davranış olduğunu biliyoruz,

O değil. Varsayalım

Ben aynı derleyici yükleme kullanılarak, -std=c++11 ile tek transation gcc -std=c++98 ünitesi ve başka derlemek. İki nesne dosyasını bağlayabileceğim ve iyi tanımlanmış bir program alabileceğim herhangi bir garanti var mı?

Evet, bu desteklenen ve eserleri (orada istisnalar birinde -fshort-enums değil diğerleri gibi açıkça-ABI değişen seçeneklerin bir nesnede Debug Mode etkinleştirme ve diğer veya kullanmak gibi, ama o olmalı Her iki nesne için de aynı -std seçeneğini kullansanız bile işe yaramayacağı için açık olun.

Bildiğim kadarıyla söyleyebilirim, potansiyel problemler nedeniyle sadece farklı Makrolara kütüphane başlıkların farklı görünümler gelebilir ve bu da bu en iyi ihtimalle, yeni üye işlevlerini, ama asla üye nesneleri eklersiniz standart kütüphane sınıfları.

Sağ.

Bu, daha büyük bir projenin farklı bölümlerini farklı dil lehçesi seçenekleri ile derlemek için kabul edilebilir mi?

GCC için, evet, kesinlikle. Kanıtın doğru olduğu gibi, libstdc++.so'un -std=c++98 ile oluşturulmuş bazı nesneler içerdiğini ve bazılarının -std=c++14 ile oluşturulduğunu düşünün.

Güncelleme: Eğer dik bir soru eklemek gerekir: Ne GCC iki farklı versiyonunu (4.3 ve 4.6 diyelim) kullanma hakkında ama wht aynı lehçesi seçeneği (-std = C++ 98)? Bu GCC dokümantasyonundaki listeleme, kütüphanenin 4.2.2 ve 4.6 arasındaki her iki yönde uyumlu olduğunu göstermektedir. Bu sürümü ile derlenen nesne yeni bir sürümü tanıtıldı ve bulunmayan edildi semboller bağlı olabilir çünkü

her iki yönde, sen GCC 4.6 (veya daha yeni) den libstdc++.so kullanmak gerekir değil büyük libstdc++.so kütüphanesi.

https://stackoverflow.com/a/49119902/981959

0

Dil ABI de ilgili bazı bilgiler aynıdır, ancak STL ABI farklıdır. Bu nedenle, -std = C++ 98 -std = C++ 11 ile derlenmiş kütüphaneleri karıştırma önerilmemektedir. Verileri görüntü sınırları boyunca geçirirken çökmeler olabilir.

(Yalnızca "C" işlevlerini çağırır ve yalnızca POD'ları iletirseniz işe yarayabilir). Mixing different C++ standards with GCC

+0

Bu wiki sayfası güncel görünmüyor :-( –