C işlevleri neden adlarla karıştırılamıyor?


136

Son zamanlarda bir röportaj yaptım ve bir soru extern "C"C ++ kodunda kullanımının ne olduğunu sordu . C adı-mangling kullanmaz gibi C ++ kodu C işlevlerini kullanmak olduğunu yanıtladı. C'nin neden isim yönetimi kullanmadığını ve dürüst olmak gerekirse cevaplayamadığım soruldu.

C ++ derleyicisi işlevleri derlediğinde, özellikle derleme zamanında çözülmesi gereken C ++ 'da aynı adın aşırı yüklenmiş işlevlerine sahip olabileceğinden, işleve özel bir ad verdiğini anlıyorum. C de, işlevin adı aynı kalır, ya da önce _ ile birlikte kalır.

Benim sorgu: C ++ derleyicisinin C işlevlerini de değiştirmesine izin vermede sorun nedir? Derleyicinin onlara hangi isimleri verdiğinin önemli olmadığını düşünürdüm. C ve C ++ 'da işlevleri aynı şekilde çağırıyoruz.


75
C'nin isimleri değiştirmesi gerekmez , çünkü aşırı fonksiyon yüklemesi yoktur.
EOF

9
C ++ derleyicisi işlev adlarını yönetirse, C kitaplıklarını C ++ koduyla nasıl bağlarsınız?
Mat

6
"C, ad yönetimini kullanmadığı için C ++ kodunda C işlevlerini kullanmak olduğunu söylemiştim." - Bence tam tersi. Extern "C", C ++ işlevlerini bir C derleyicisinde kullanılabilir hale getirir. kaynak
rozina

3
@ Engineer999: Ayrıca C ++ olan C alt kümesini bir C ++ derleyicisiyle derlerseniz, işlev adları gerçekten karışır. Ancak, farklı derleyicilerle oluşturulan ikili dosyaları bağlamak istiyorsanız, ad yönetimi istemezsiniz.
EOF

13
C yapar mangle isimler. Normalde karıştırılan ad, önünde bir alt çizgi bulunan işlevin adıdır. Bazen işlevin adı ve ardından alt çizgi gelir. extern "C"adı "C" derleyicisinin yaptığı gibi değiştirmeyi söylüyor.
Pete Becker

Yanıtlar:


187

Yukarıda bir çeşit cevap vardı, ama bazı şeyleri bağlam içine sokmaya çalışacağım.

İlk önce C önce geldi. Bu nedenle, C'nin yaptığı şey, bir çeşit "varsayılan" dır. İsimleri değiştirmez, çünkü değildir. İşlev adı, işlev adıdır. Küresel bir küreseldir, vb.

Sonra C ++ geldi. C ++, C ile aynı bağlayıcıyı kullanmak ve C ile yazılmış kodla bağlantı kurabilmek istiyordu. Ancak C ++, C'yi "mangling" (ya da eksikliği) olduğu gibi bırakamadı. Aşağıdaki örneği inceleyin:

int function(int a);
int function();

C ++ 'da, bunlar farklı gövdelere sahip farklı işlevlerdir. Bunlardan hiçbiri karıştırılmazsa, her ikisine de "işlev" (veya "_function") denir ve bağlayıcı bir sembolün yeniden tanımlanmasından şikayet eder. C ++ çözümü, bağımsız değişken türlerini işlev adına dönüştürmekti. Böylece, biri çağrılır _function_intve diğeri çağrılır _function_void(gerçek yönetim şeması değil) ve çarpışmadan kaçınılır.

Şimdi bir sorunumuz kaldı. Eğer int function(int a)bir C modülünde tanımlanmış ve biz sadece kod C ++ onun başlığını (yani beyan) alıp onu kullanıyoruz, derleyici ithalat bağlayıcı bir talimat üretecektir _function_int. İşlev tanımlandığında, C modülünde buna çağrılmadı. Denirdi _function. Bu bir bağlayıcı hatasına neden olur.

Bu hatayı önlemek için , fonksiyonun beyanı sırasında, derleyiciye bir C derleyicisi ile bağlantı kurmak veya derlemek için tasarlanmış bir işlev olduğunu söyleriz:

extern "C" int function(int a);

C ++ derleyicisi artık içe _functionaktarmayı biliyor _function_intve her şey yolunda.


1
@ShacharShamesh: Bunu başka bir yerde sordum, ama, C ++ derlenmiş kitaplıklarında bağlantı kurmaya ne dersiniz? Derleyici bir C ++ derlenmiş kitaplığındaki işlevlerden birini çağıran kodumu adım atarken ve derlerken, bildirimini veya işlev çağrısını görmede hangi adın değiştirileceğini veya işleve verileceğini nasıl bilebilir? Tanımlandığı yerde, başka bir şeye ad-yönetildiğini nasıl bilebilirim? Peki C ++ 'da standart bir ad-mangling yöntemi olmalı?
Mühendis999

2
Her derleyici bunu kendi özel yöntemiyle yapar. Her şeyi aynı derleyici ile derliyorsanız önemli değil. Ancak, örneğin, Microsoft'un derleyicisiyle oluşturduğunuz bir programdan Borland'ın derleyicisiyle derlenmiş bir kütüphane kullanmaya çalışırsanız, iyi şanslar; ihtiyacınız olacak :)
Mark VY

6
@ Engineer999 Taşınabilir C ++ kitaplıkları olarak neden böyle bir şey olmadığını merak ettiniz, ancak derleyicinin (ve standart kitaplığın) tam olarak hangi sürümünü (ve bayraklarını) kullanmanız gerektiğini belirtiyorlar veya sadece bir C API'sini dışa aktarıyorlar mı? İşte böyle. C ++, şimdiye kadar icat edilen en az taşınabilir dildir, C ise tam tersidir. Bu konuda çabalar var, ancak şimdilik gerçekten taşınabilir bir şey istiyorsanız, C ile yapışacaksınız.
Voo

1
@Voo Peki, teoride -std=c++11, örneğin standarda bağlı kalarak taşınabilir kod yazabilmeli ve standart dışında herhangi bir şey kullanmaktan kaçınabilmelisin. Bu, Java sürümünü bildirmekle aynıdır (daha yeni Java sürümleri geriye dönük uyumlu olsa da). İnsanların derleyiciye özel uzantılar ve platforma bağlı kod kullanması standart hatası değildir. Öte yandan, standartta eksik olan birçok şey (özellikle IO, soketler gibi) olduğu için onları suçlayamazsınız. Komite yavaş yavaş buna yaklaşıyor gibi görünüyor. Bir şeyi kaçırırsam düzelt.
mucaho

14
@mucaho: kaynak taşınabilirliği / uyumluluğu hakkında konuşuyorsunuz. yani API. Voo, yeniden derleme olmadan ikili uyumluluktan bahsediyor . Bu, ABI uyumluluğu gerektirir . C ++ derleyicileri ABI'larını sürümler arasında düzenli olarak değiştirir. (örneğin g ++, sabit bir ABI'ye sahip olmaya bile çalışmaz. ABI'yi sadece eğlence için kırmadıklarını varsayıyorum, ancak kazanılacak bir şey olduğunda ABI değişikliği gerektiren değişikliklerden kaçınmıyorlar ve başka iyi bir yol yok. yapmak için.).
Peter Cordes

45

Onlar "olamaz", onlar o değil değil genel olarak.

Bir C kütüphanesinde bir işlevi çağırmak istiyorsanız foo(int x, const char *y), C ++ derleyici mangle'ınızı foo_I_cCP()(ya da her neyse, sadece burada yerinde bir mangling şeması oluşturdu) içine girmesine izin vermek iyi değildir .

Bu ad çözümlenmez, işlev C'dir ve adı bağımsız değişken türleri listesine bağlı değildir. Bu yüzden C ++ derleyicisi bunu bilmeli ve mangling yapmaktan kaçınmak için bu işlevi C olarak işaretlemelidir.

Bahsedilen C işlevinin, kaynak koduna sahip olmadığınız bir kitaplıkta olabileceğini, tek sahip olduğunuz önceden derlenmiş ikili ve başlık olduğunu unutmayın. Yani C ++ derleyiciniz "bu kendi işi" yapamaz, sonuçta kütüphanede ne olduğunu değiştiremez.


Bu benim eksik olduğum kısım. Neden C ++ derleyicisi sadece bir bildirim adını gördüğünde ya da çağrıldığını gördüğünde bir işlev adını değiştirir? Sadece uygulamalarını gördüğünde işlev adlarını değiştirmekle kalmaz mı? Bu benim için daha anlamlı olur
Engineer999

13
@ Engineer999: Tanım için bir adınız ve deklarasyon için başka bir adınız olabilir mi? "Brian adında arayabileceğiniz bir işlev var." "Tamam, Brian'ı arayacağım." "Üzgünüm, Brian diye bir işlev yok." Buna Graham deniyor.
Yörüngedeki Hafiflik Yarışları

C ++ derlenmiş kitaplıklarında bağlantı kurmaya ne dersiniz? Derleyici bir C ++ derlenmiş kitaplığındaki işlevlerden birini çağıran kodumuza adım attığında ve derlediğinde, yalnızca bildirimini veya işlev çağrısını görmede hangi adın değiştirileceğini veya işleve verileceğini nasıl bilebilir?
Mühendis999

1
@ Engineer999 Her ikisi de aynı mangling konusunda hemfikir olmalıdır. Bu yüzden başlık dosyasını görüyorlar (unutmayın, yerel DLL'lerde çok az meta veri var - başlıklar bu meta veriler) ve "Ah, doğru, Brian gerçekten Graham olmalı". Bu işe yaramazsa (örn. İki uyumsuz yönetim şeması ile), doğru bir bağlantı elde edemezsiniz ve uygulamanız başarısız olur. C ++, bunun gibi birçok uyumsuzluğa sahiptir. Pratikte, açık bir şekilde karışık adı kullanmanız ve yanınızda karıştırmayı devre dışı bırakmanız gerekir (örneğin kodunuza Brian'ı değil Graham'ı yürütmesini söylersiniz). In gerçek uygulamada ... extern "C":)
Luaan

1
@ Engineer999 Yanılıyor olabilirim, ancak belki de Visual Basic, C # veya Java (veya bir dereceye kadar Pascal / Delphi) gibi dillerde deneyiminiz var mı? Bunlar birlikte çalışmayı son derece basit gösterir. C ve özellikle C ++ 'da, her şeyden başka. Onurlandırmanız gereken çok sayıda çağrı kuralı var, hangi hafızadan kimin sorumlu olduğunu bilmelisiniz ve DLL'lerin kendileri yeterli bilgi içermediğinden, özellikle işlev bildirimlerini bildiren başlık dosyalarına sahip olmalısınız. saf C. Bir başlık dosyanız yoksa, genellikle DLL dosyasını kullanmak için koda dönüştürmeniz gerekir.
Luaan

32

C ++ derleyicisinin C işlevlerini de değiştirmesine izin vermekle ilgili sorun nedir?

Artık C işlevleri olmayacaklardı.

Bir işlev sadece bir imza ve tanım değildir; bir işlevin nasıl çalıştığı büyük ölçüde çağrı kuralı gibi faktörler tarafından belirlenir. Platformunuzda kullanım için belirtilen "Uygulama İkili Arabirimi", sistemlerin birbirleriyle nasıl konuştuğunu açıklar. Sisteminiz tarafından kullanılan C ++ ABI, bir ad yönetim şeması belirler, böylece bu sistemdeki programlar, kitaplıklardaki işlevleri nasıl çağıracağını bilir. (Harika bir örnek için C ++ Itanium ABI'yi okuyun. Neden gerekli olduğunu çok hızlı bir şekilde göreceksiniz.)

Aynı şey sisteminizdeki C ABI için de geçerlidir. Bazı C ABI'lerin aslında bir ad yönetim şeması (örn. Visual Studio) vardır, bu nedenle bu, "ad yönetimini kapatma" hakkında daha az ve belirli işlevler için C ++ ABI'den C ABI'ye geçiş hakkında daha fazladır. C işlevlerini C ABI (C ++ ABI yerine) ile ilgili olan C işlevleri olarak işaretleriz. Bildirim, tanımla eşleşmelidir (aynı projede veya bazı üçüncü taraf kütüphanelerinde olsun), aksi takdirde bildirim anlamsızdır. Bu olmadan, sisteminiz bu işlevleri nasıl bulacağınızı / çağıracağınızı bilemez.

Platformların neden C ve C ++ ABI'leri aynı olduğunu ve bu "problemden" kurtulmalarını tanımlamamasına gelince, bu kısmen tarihseldir - orijinal C ABI'leri, ad alanları, sınıflar ve operatör aşırı yüklemesi olan C ++ için yeterli değildi. bir şekilde bir sembolün adıyla bilgisayar dostu bir şekilde temsil edilmesi gerekiyor - ancak biri C ++ programlarına uymak için C programlarının haksız olduğunu C topluluğunda haksız olduğunu iddia edebilir. ABI, birlikte çalışabilirlik isteyen bazı insanlar uğruna.


2
+int(PI/3), ancak bir tane tuzla: "C ++ ABI" dan bahsetmek için çok dikkatli olurum ... AFAIK, C ++ ABI'leri tanımlama girişimleri var , ancak gerçek de facto / de jure standartları yok - isocpp.org/files olarak /papers/n4028.pdf devletleri (ve yürekten katılıyorum), alıntı, C ++ 'ın, C ++ harici C ++ alt kümesine başvurarak, istikrarlı bir ikili ABI ile API'yi yayınlamanın her zaman bir yolunu desteklemesi çok ironiktir. ”. . C++ Itanium ABIsadece - Itanium için bazı C ++ ABI ... stackoverflow.com/questions/7492180/c-abi-issues-list

3
@vaxquis: Evet, "C ++ ABI" değil, "C ++ ABI" ile aynı şekilde her evde çalışmayan bir "ev anahtarı" var. Ben ifadeyle kapalı başlatarak mümkün olduğunca açık olarak yapmaya çalıştı ama o, net olabilir Tahmin "C ++ ABI sisteminiz tarafından kullanılıyor " . Temizleyiciyi kısalık için daha sonraki ifadelerde bıraktım, ancak burada karışıklığı azaltan bir düzenlemeyi kabul edeceğim!
Yörüngedeki Hafiflik Yarışları

1
AIUI C abi bir platformun mülkiyeti olma eğilimindeyken, C ++ ABI'ler tek bir derleyicinin ve hatta bir derleyicinin bireysel bir sürümünün bir özelliği olma eğilimindeydi. Dolayısıyla, farklı satıcı araçlarıyla oluşturulmuş modüller arasında bağlantı kurmak istiyorsanız, arayüz için bir C abi kullanmak zorunda kaldınız.
plugwash

"Ad-mangled fonksiyonları artık C fonksiyonları olmayacak" ifadesi abartılıdır - mangled ad biliniyorsa, düz vanilya C'den ad-mangled fonksiyonlarını çağırmak mümkündür. Adın değişmesi onu C ABI'ye daha az bağlı hale getirmez, yani daha az C işlevi yapmaz. Diğer yol daha mantıklı - C ++ kodu, "C" olarak bildirmeden bir C fonksiyonunu çağıramazdı çünkü callee ile bağlantı kurmaya çalışırken
Peter - Monica'yı eski

@ PeterA.Schneider: Evet, başlık ifadesi abartılı. Cevabın tamamını geri kalanı uygun olgusal ayrıntı içeriyor.
Yörüngedeki Hafiflik Yarışları

21

Aslında MSVC yapar basit bir şekilde rağmen, mangle C isimleri. Bazen @4veya başka bir küçük sayı eklenir . Bu, çağrı kurallarına ve yığın temizleme ihtiyacına ilişkindir.

Yani öncül kusurlu.


2
Bu gerçekten isim mangling değil. Bu, yürütücülerin farklı çağrı kurallarına sahip işlevlerle oluşturulan DLL'lere bağlanmasını önlemek için yalnızca satıcıya özgü bir adlandırma (veya ad adorning) kuralıdır.
Peter

2
Bir ile başlamaya ne dersiniz _?
OrangeDog

12
@Peter: Kelimenin tam anlamıyla aynı şey.
Orbit'te Hafiflik Yarışları

5
@Frankie_C: "Arayan kişi yığını temizler" herhangi bir C standardı tarafından belirtilmez: hiçbir çağrı kuralı bir dil perspektifinden diğerinden daha standart değildir.
Ben Voigt

2
Ve MSVC perspektifinden bakıldığında, "standart çağrı kuralı" sadece sizin seçeceğiniz şeydir /Gd, /Gr, /Gv, /Gz. (Yani, bir işlev bildirimi bir çağrı kuralını açıkça belirtmedikçe, standart çağrı kuralı kullanılır.). __cdeclHangisinin varsayılan standart arama kuralı olduğunu düşünüyorsunuz .
MSalters

13

Kısmen C ile yazılmış ve başka bir dilde kısmen yazılmış programlara sahip olmak çok yaygındır (genellikle montaj dili, ancak bazen Pascal, FORTRAN veya başka bir şey). Programların, her şey için kaynak koduna sahip olmayan farklı insanlar tarafından yazılmış farklı bileşenler içermesi yaygındır.

Çoğu platformda, bir derleyicinin belirli bir türle belirli bir türdeki argümanları kabul eden ve belirli bir türün değerini döndüren bir işlev üretmek için ne yapması gerektiğini açıklayan bir ABI [Uygulama İkili Arabirimi] adı verilen bir özellik vardır. Bazı durumlarda, bir ABI birden fazla "çağrı kuralı" tanımlayabilir; bu tür sistemler için derleyiciler genellikle belirli bir işlev için hangi çağrı kuralının kullanılması gerektiğini belirtmek için bir araç sağlar. Örneğin, Macintosh'ta, Toolbox yordamlarının çoğu Pascal çağrı kuralını kullanır, bu nedenle "LineTo" gibi bir şeyin prototipi şöyle olur:

/* Note that there are no underscores before the "pascal" keyword because
   the Toolbox was written in the early 1980s, before the Standard and its
   underscore convention were published */
pascal void LineTo(short x, short y);

Bir projedeki kodun tamamı aynı derleyici kullanılarak derlenmişse, derleyicinin her işlev için hangi adı dışa aktardığı önemli değildir, ancak birçok durumda C kodunun diğer araçlar kullanılarak derlenen işlevleri çağırması ve mevcut derleyici ile yeniden derlenemez [ve C'de bile olmayabilir]. Bağlayıcı adını tanımlayabilmek, bu tür işlevlerin kullanımı için kritik öneme sahiptir.


Evet, cevap bu. Sadece C ve C ++ ise, neden bu şekilde yapıldığını anlamak zordur. Anlamak için, şeyleri eski statik bağlanma yolunun bağlamına koymalıyız. Statik bağlama, Windows programcılarına ilkel görünüyor ama C birincil nedenidir olamaz bozmak isimler.
user34660

2
@ user34660: Qutie değil. C'nin uygulanması, dışa aktarılabilir adların yönetilmesini ya da ikincil özelliklerle ayırt edilen birden fazla benzer adlandırılmış sembolün varlığına izin vermesini gerektiren özelliklerin varlığını zorunlu kılamamasının sebebidir.
supercat

bu tür şeyleri "zorunlu kılma" girişimleri olduğunu veya C ++ 'dan önce C için uzantılar olduğunu biliyor muyuz?
user34660

@ user34660: Re "Statik bağlantı Windows programcıları için ilkel görünüyor ...", ancak dinamik bağlantı bazen Linux kullanan insanlara büyük bir PITA gibi gözüküyor, X programını yüklerken (muhtemelen C ++ ile yazılmış) belirli sürümleri izlemek ve yüklemek zorunda olduğunuz anlamına geliyor sisteminizde halihazırda farklı sürümlerine sahip olduğunuz kitaplıklardan oluşur.
jamesqf

@jamesqf, evet, Unix'in Windows'tan önce dinamik bağlantısı yoktu. Unix / Linux'ta dinamik bağlantı hakkında çok az şey biliyorum, ancak genel olarak bir işletim sisteminde olabileceği kadar sorunsuz değil gibi görünüyor.
user34660

12

Gerçekleştirilen bazı teğet tartışmalara değinmek için bir cevap daha ekleyeceğim.

C ABI (uygulama ikili arayüzü) başlangıçta, yığındaki argümanları ters sırada (yani - sağdan sola itilmiş) iletmek için çağrıldı; burada arayan da yığın deposunu serbest bırakır. Modern ABI aslında argümanları geçiş argümanları için kullanır, ancak mangling düşüncelerinin çoğu o orijinal yığın argümanına geçer.

Orijinal Pascal ABI, aksine, argümanları soldan sağa itti ve callee argümanları patlatmak zorunda kaldı. Orijinal C ABI, iki önemli noktada orijinal Pascal ABI'dan üstündür. Bağımsız değişken itme sırası, ilk bağımsız değişkenin yığın ofsetinin her zaman bilinmesi anlamına gelir ve bilinmeyen sayıda bağımsız değişkene sahip işlevlere izin verir, burada erken bağımsız değişkenler kaç tane bağımsız değişken olduğunu kontrol eder (ala printf).

C ABI'nin daha üstün olduğu ikinci yol, arayan ve arayan kişinin kaç argüman olduğu konusunda anlaşamaması durumundaki davranıştır. C durumunda, sonuncuyu geçen argümanlara gerçekten erişmediğiniz sürece, kötü bir şey olmaz. Pascal'da, yığından yanlış sayıda bağımsız değişken açılır ve tüm yığın bozulur.

Orijinal Windows 3.1 ABI, Pascal'a dayanıyordu. Bu nedenle, Pascal ABI (soldan sağa argümanlar, callee çıkar) kullandı. Argüman numarasındaki herhangi bir uyuşmazlık, yığın bozulmasına neden olabileceğinden, bir karıştırma düzeni oluşturuldu. Her işlev adı, bağımsız değişkenlerinin boyutunu bayt cinsinden gösteren bir sayı ile karıştırılmıştır. Yani, 16 bit makinede aşağıdaki fonksiyon (C sözdizimi):

int function(int a)

İçin karıştırılmış oldu function@2çünkü intiki bayt genişliğinde. Bu, bildirim ve tanım uyuşmazlığı durumunda, bağlayıcının çalışma zamanında yığını bozmak yerine işlevi bulamayacağı şekilde yapılmıştır. Tersine, program bağlanırsa, çağrının sonunda yığından doğru sayıda bayt geldiğinden emin olabilirsiniz.

32 bit Windows ve sonrası için stdcallABI kullanın. Pascal ABI'ye benzer, ancak push sırası C'deki gibi sağdan sola. Pascal ABI gibi, mangling adı da yığının bozulmasını önlemek için argüman bayt boyutunu işlev adına karıştırır.

Burada başka bir yerde yapılan iddiaların aksine, C ABI, Visual Studio'da bile işlev adlarını değiştirmez. Tersine, stdcallABI spesifikasyonu ile dekore edilmiş mangling fonksiyonları VS'ye özgü değildir. GCC, Linux için derlerken bile bu ABI'yi destekler. Bu, Linux tarafından derlenen ikili dosyaların Windows derlenmiş DLL'lerine çalışma süresi bağlantısına izin vermek için kendi yükleyicisini kullanan Wine tarafından yaygın olarak kullanılır .


9

C ++ derleyicileri, aksi takdirde aynı olacak olan aşırı yüklenmiş işlevler için benzersiz sembol adlarına izin vermek amacıyla ad yönetimi kullanır. Temel olarak fonksiyon tabanlı bir seviyede polimorfizme izin veren argüman türlerini de kodlar.

C, fonksiyonların aşırı yüklenmesine izin vermediğinden buna ihtiyaç duymaz.

Ad yönetimi, bir 'C ++ ABI'ye güvenememenin bir (ama kesinlikle tek değil!) Nedeni olduğunu unutmayın.


8

C ++, ona bağlanan veya bağlandığı C kodu ile birlikte çalışabilmek ister.

C, isim tarafından yönetilmeyen işlev adlarını bekler.

C ++ onu karıştırdıysa, C'den dışa aktarılan karışık olmayan işlevleri bulamaz veya C + C'nin dışa aktardığı işlevleri bulamaz. C bağlayıcısının beklediği adı alması gerekir, çünkü C ++ 'dan geldiğini veya C ++' a gittiğini bilmiyor.


3

C işlevlerinin ve değişkenlerinin adlarını yönetmek, bağlantı zamanında türlerinin kontrol edilmesini sağlar. Şu anda, tüm (?) C uygulamaları bir dosyada bir değişken tanımlamanıza ve onu başka bir dosyada işlev olarak adlandırmanıza izin verir. Veya imzası yanlış olan bir işlevi bildirebilirsiniz (örn void fopen(double). Sonra da çağırabilirsiniz).

1991'de geri manevra kullanarak C değişkenlerinin ve fonksiyonlarının tip-güvenli bağlantısı için bir plan önerdim . Şema asla kabul edilmedi, çünkü burada belirtildiği gibi, bu geriye dönük uyumluluğu bozacaktır.


1
"Türlerinin bağlantı zamanında kontrol edilmesine izin ver" anlamına gelir . Türleri olan derleme zamanında kontrol, ancak farklı derleme birimlerinde kullanılan bildirimleri kabul edip unmangled isimlerle bağlama kontrol edemez. Ve kabul etmezlerse, temelde kırılmış ve düzeltilmesi gereken yapı sisteminizdir.
cmaster - reinstate monica
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.