İşletim sistemleri neden C ve C ++ 'da düşük seviye işler yapıyor? Neden sadece C ++ değil?


20

Windows için Wikipedia sayfasında, Windows'un bootloader ve görev değiştirici için Assembly'de ve çekirdek rutinleri için C ve C ++ ile yazıldığını belirtir .

IIRC, bir extern "C"'d bloğundan C ++ işlevlerini çağırabilirsiniz . Çekirdek işlevleri için C'yi kullanarak saf C uygulamaları bunları kullanabilir ( printfve benzeri) alabilirim, ancak sadece bir extern "C "blokta sarılabilirlerse , neden kod C?


10
"C ++ varken neden C kullanıyorsunuz?" burada sorularınız mı var? Bu mutlaka bunlardan herhangi birinin kopyası değil ama onlar olan ilgili.

1
"C ++ fonksiyonlarını bir extern'den çağırabilirsiniz" C "'c bloğu olarak C ++" Yani C fonksiyonlarını çağırabilirsiniz ...?
Code-Guru

@ Code-Guru no, çünkü dışa aktarılan C ve C ++ işlevleri arasındaki tek fark dekorasyon adı ve C ++ 'da thisdeğişkenin eklenmesi
Cole Johnson

2
Bir ISR'de bir istisna atın ve ne olduğunu görün
James

Yine başka bir C ve C ++ sorusu.
Machado

Yanıtlar:


31

Çoğunlukla tarihsel nedenlerden dolayı. Windows çekirdeğinin bazı kısımları orijinal olarak C dilinde yazılmıştır, çünkü 1983, otuz yıl önce, Windows 1.0 piyasaya sürüldüğünde, C ++ zar zor serbest bırakılmıştır. Microsoft, geriye dönük uyumluluğu bir satış noktası haline getirdiğinden ve C ++ 'da C-parçalarının hata uyumlu bir versiyonunu yeniden yazmak etkili bir fayda sağlamak için çok fazla çaba gerektirdiğinden, artık bu C-kütüphaneleri orada "sonsuza kadar" kalacak.


+1, sanırım en gerçekçi cevap (sadece C ++ 'dan hoşlanmayan veya bu düşük seviyeli şeyler için C ++ derleyicilerine güvenmeyen bazı Windows çekirdek geliştiricileri olabilir). Örneğin, buraya bakın stackoverflow.com/questions/520068/… , Linux çekirdeği neden C ile yazılmış?
Doc Brown

@ back2dos - C kodları kullanılmayacak olsa da bu, kullanılacağı veya güncellenmeyeceği anlamına gelmez. Orijinal olarak yazılmış ve Windows 8'de bir C ++ kitaplığı taşınan bir C kitaplığında bulunan bir şey yapan en az bir yöntem olduğunu garanti ediyorum
Ramhound

8
Windows'un son sürümlerinde herhangi bir Windows 1.0 kodu olduğuna inanarak zorlanıyorum. Windows ME, Windows NT kod tabanını temel almayan son Windows sürümüdür. Ve bu bile büyük ölçüde yeni RT çekirdeği ile değiştirildi (ki, anladığım kadarıyla, geriye dönük uyumluluk yolunda çok fazla söz vermiyor).
TMN

@TMN: - Ben Win 1,0 orada artık giden yolda eminim argüman ya büyük ihtimalle doğrudur vardı hala geçerli Win8 kod tabanının bir parçası olan C ile yazılmış kütüphaneler bir sürü ve MS kimse herhangi görür C ++ 'da yeniden yazmak için yarar.
Doc Brown

1
Zaten Windows çekirdeğiyle konuşan neredeyse hiç kod yok. Temel olarak, sadece sürücüler yapar. Uygulamalar genellikle Win32 API veya muhtemelen POSIX API ile konuşur.
MSalters

24

Çoğu insanın işaret ettiği gibi, nedenler çok tarihseldir, ancak kimsenin bahsetmediği başka bir şey vardır ve inanıyorum ki insanlar hala düşük seviye için C kodu yazıyorlar.

C, özelliğin (nispeten) kısa olması anlamında küçük bir dildir. C ++ çok büyük ve bu bir understatement. Bu, programcı için çok önemli olmayabilir (her ne kadar sanırım), ancak resmi doğrulama yapmak istiyorsanız son derece önemlidir . Ayrıca, C kodu analizi için, hataları önlemeye yardımcı olabilecek yerleşik araçlar vardır.

Ve bu, dağıtılan bir hatanın maliyetinin endüstrinin geri kalanına göre çok yüksek olduğu gömülü yazılımda çok önemlidir (Web'i karşılaştırın, hemen tüm kullanıcılara bir yama uygulayabilirsiniz). Kritik görev yazılımlarından ve tıbbi şeylerden bahsetmiyorum bile.

C'yi düşük seviye programlamadaki baskın konumundan BitC gibi daha iyi dillerle değiştirme girişimleri olmuştur, ancak şimdiye kadar başarılı olmamıştır.


4
+1 Saf C'deki kritik görev yazılımından bahsetmek için (örn. Havacılık yazılımı). Bununla birlikte, tıbbi yazılımda C ++ da kullanılır (C ++ 'da son derece zor olacak resmi bir doğrulama yerine kapsamlı testler kullanılır).
Giorgio

1
Ayrıca, C'nin oldukça başarılı bir güvenli alt kümesi MISRA-C vardır. C ++ için eşdeğerler vardır, ancak bunlar endüstri standardı değildir (henüz). Güvenlik açısından kritik programlamadaki eğilim, kütüphanelerin ve derleyicilerin de MISRA gibi güvenli bir alt kümeyi kullanmaya zorlanmasıdır. Tüm C ++ standart kütüphanesinin MISRA-C ++ uyumlu bir versiyonunu yeniden yazmak büyük olasılıkla bir kabus olacaktır.

2
@Lundin MISRA yönergeleri güvenli bir alt küme değildir - hala ham işaretçiler ve C'yi güvensiz hale getiren diğer birçok özelliğiniz vardır - esas olarak uygulamaya özgü davranışı kullanmamaya veya belgelememeye odaklanırlar.
Pete Kirkham

@PeteKirkham MISRA-C, en klasik işaretçi hatalarını yakalayacak ve statik analizi zorunlu kılacaktır. Endüstri güvenliği standartları (IEC 61508 ve diğerleri), MISRA-C'yi C'nin güvenli bir alt kümesi olarak onaylamaktadır. Sınırlı araçla SPARK Ada'yı seçmediğiniz sürece, kritik öneme sahip yazılımlar için başka pek çok faydalı alternatif yoktur. destek.

2
Bu, doğru olduğu için en iyi cevap olarak seçilmelidir. C'nin sadece tarihsel nedenlerle kullanılmasını öneren diğerleri kendi başına histeriktir.
Rob

15
  1. C çalışma zamanı çok daha küçük.
  2. C ++ 'ın alt düzey yapılara çevrilmesi C'den daha az şeffaftır (İki hızlı örnek için referanslara ve araçlara bakınız)
  3. C genellikle stabil bir ABI'ye sahiptir. C ++ genellikle bunu yapmaz. Bu, minimum düzeyde, sistem çağrısı arayüzünün C stili olması gerektiği anlamına gelir. Ayrıca, herhangi bir dinamik modül istiyorsanız, tutarlı bir ABI'ye sahip olmak çok yardımcı olur.

(2) ve (3) için +1. (1) ile ikna olmadım.
Thomas Eding

7
@Thomas Eding: C ++ çalışma zamanı C çalışma zamanının yanı sıra özel durumlar, RTTI ve başka bir bellek ayırıcı gibi C ++ özelliklerinden oluşur. Bunun daha büyük olup olmadığı konusunda YMMV . (Ve sonra standart kütüphane var ...)
wnoise

Ah, istisnaları ve yeni / silme havuzlarını unuttum. RTTI Yine de kullanmıyorum: D
Thomas Eding

11

Sebepler teknik değil. Biraz montaj kaçınılmaz, ancak ara sıra C'yi kullanmak zorunda değiller, istiyorlar . Şirketim, neredeyse tamamen C ++ ile yazılmış kendi özel çekirdeğini kullanıyor, ancak gömülü çekirdeğimiz monolitik olarak C ++ uygulamalarımızla derlendiği için çekirdeğe C arayüzünü desteklememiz gerekmiyor. Eğer bir C arayüzüne sahip olduğunda, o olsa bile, C arayüz kod yazmak genellikle daha kolaydır mümkün kullanmak extern "C"C ++ bunu yazmak için.

Çoğunlukla üçüncü taraf kodu nedeniyle C dosyalarının dağılması bile var. Üçüncü taraf düşük düzeyli kod neredeyse her zaman C'de sağlanır, çünkü C kodunu bir C ++ uygulamasına dahil etmenin diğer yollardan çok daha kolaydır.


6

Çekirdek geliştiricileri genellikle, kaynaktan hemen anlaşıldığı zaman, kodun gerçekte ne yaptığını daha mutlu hisseden insanlardır.

C ++, kodun düz C kodundan daha fazlasını gizlediğini gizleyen daha birçok özelliğe sahiptir: aşırı yükler, sanal yöntemler, şablonlar, referanslar, atar ... C ++, C ++ 'ı bile anlamak için ustalaşmanız gereken çok daha fazla sözdizimine sahiptir kodunu kullanarak.

C ++ 'ın gücü, daha sonra uygulama geliştirmeyi bir çırpıda yapan kütüphaneler ve çerçeveler oluşturmak için çok güçlü bir araç olduğunu düşünüyorum. Çoğu zaman C ++ uygulama geliştiricisi, o kütüphaneyi kullanarak uygulama oluşturma konusunda çok yetkin olsa bile, bir kütüphanenin şablonla dolu iç kısımlarında tamamen kaybolurdu. Ve bir C ++ kütüphanesi doğru yazmak çok zor bir programlama görevidir ve sadece uygulama geliştiricisinin yararına mükemmel bir çerçeve sağlamak için yapılır. C ++ kütüphaneleri dahili olarak basit değildir, uygulama programcıları açısından sadece güçlü ancak basittir (veya olabilirler).

Ancak çekirdek API bir C ++ API olamaz, bir dil agnostik API olmalıdır, bu yüzden C ++ 'daki güzel şeylerin çoğu doğrudan bu arayüzde kullanılamaz. Ayrıca, çekirdek gerçekten bir kütüphane uygulaması oluşturmayı kolaylaştırmak için mantıksal olarak bir kütüphaneye giderek daha fazla çaba ile bağımsız olarak geliştirilen "kütüphane" ve "uygulama" parçalarına bölünmemiştir.

Ayrıca, güvenlik ve kararlılık bir çekirdek içinde daha kritiktir ve sanal yöntemler düz geri çağrılardan veya diğer C-benzeri mekanizmalardan çok daha dinamiktir ve bu nedenle yalıtılması ve doğrulanması çok daha zordur.

Kısacası, elbette C ++ olarak bir çekirdek de dahil olmak üzere herhangi bir C programı yazarken, C ++ 'ın gücünün çoğu çekirdekte iyi kullanılmaz. Ve birçoğu, programlama araçlarının yapmamanız gereken şeyleri yapmanızı engellemesi gerektiğini savunuyor. C ++ olmaz.


+1. Bir çekirdek geliştirici olarak "temel kuralım", "önbellek satırlarına kolayca dokunduğunu" tahmin edemezseniz, kullandığınız dilin yarardan çok zarar görmesidir.
Brendan

Açıklama: Çekirdekler için CPU'nun zamanının çoğunu kullanıcı boşluğunda geçirdiğini ve çekirdek kodunun ara sıra kullanıldığını varsaymanız gerekir (örneğin, kullanıcı boşluğu çekirdek API'sını çağırdığında veya bir kesinti meydana geldiğinde); yani "soğuk önbellek" varsaymanız gerekir. Modern CPU'lar için (RAM'in CPU hızına göre yavaş olduğu) önbellek ve TLB kayıpları pahalıdır, bu nedenle ("soğuk önbellek" beklentisiyle birlikte) "dokunan önbellek çizgileri" metriği performans ve / veya ölçeklenebilirlik için son derece önemli bir gösterge haline gelir.
Brendan

5

Bjarne Stroustrup, Temmuz 1999'daki bir röportajda :

Bu dillerin hiçbiri diğer çağdaş dillerden radikal olarak farklı ya da önemli ölçüde daha iyi değildi. Ancak bunlar yeterince iyiydi ve şans ve sosyal faktörlerden faydalananlar


2
Hoş geldin David. Alıntı yaparken veya alıntı yaparken, referans sağlamak iyi bir fikirdir (eklendi!)
Andrew

3

C, tasarımıyla çok düşük seviyeli bir dildir. Montajcıdan bir adım uzakta; hedeflediğiniz yonga setini bilerek, az bir bilgi ile C'yi ASM'ye manuel olarak "derleyebilirsiniz". Bu tür "metale yakın" dil, yüksek düzeyde optimizasyon (performans, bellek verimliliği vb. İçin) için anahtardır. Ancak, metale bu kadar yakın olduğu için, bu dilde ücretsiz olarak fazla bir şey elde edemezsiniz; yordamsal, nesne yönelimli olmayan bir dildir ve bu nedenle bu tür yapılarla çalışmak, bellekte çok değerli yapılar oluşturmak ve tüketmek için çok sayıda kaynak kodu içerir.

C ++ "C one better" dır ve dinamik bellek ayırma, yerleşik yapı marshalling, önceden tanımlanmış büyük bir kod kütüphanesi gibi bir dizi kullanım kolaylığı özelliği ekleyerek bazı verimlilik kayıpları pahasına (yine de çok daha iyi) yönetilen çalışma zamanı ortamlarından daha fazla). Ortalama kodlayıcı için, avantajlar, kod tabanının bellek tahsisinin anal-kalıcı kontrolüne vs. ihtiyaç duymayan alanlardaki dezavantajlardan çok daha ağır basar.

İkisinin kombinasyonu oldukça geleneksel bir kombinasyon; C'yi, kod tabanının performans açısından en kritik, bellek açısından verimli alanlarını yazmak için kullanırsınız; daha sonra, uber-performansından daha zarif bir şekilde düzenlenebilen ve tasarlanabilen C ++ kodunun yöntem çağrıları ile daha soyut bir şekilde çalışabilirsiniz. , uber-oogly optimize C kodu.


2
Verimlilik ile ilgili olarak, kendimi tekrar edeceğim: (1) C ++ çalışanları size bunun saçmalık olduğunu söyleyecektir. (2) Bunun böyle olması için hiçbir neden göremediğimi söylüyorum ve somut örnekler istiyorum. Daha az verimli kod yazmanın nasıl kolay olduğunun örnekleri değil, C kadar verimli olmanın örnekleri de gereksiz çirkinlik gerektiriyor.

3
"Çirkin" tanımlayın; Ben bir yaşam için C # kod ve StackOverflow C ++ kod örnekleri her gördüğümde dilin günlük gün kullanımda ne kadar ham normal kabul edilir. Ne zaman geri C ++ şekilde kodlanmış zaman, sık sık C kodu gördüm ve cringed; elle paketleme yapı tipleri, manuel atlamalar için yürütme işaretçisi hesaplamaları, gömülü ASM ... yuck. Bazı insanlar Java / .NET programcıları arasında düşük seviyeli bilgi kaybını anıyor; Verimlilik için büyük bir nimet olduğunu düşünüyorum.
KeithS

1
Soruma cevap vermedin;) "Çirkin" ile kastediyorum "çirkin C ++ guruş standartlarına göre". Diğer bir deyişle, "modern C ++" kullanamayacağınız ve C kadar verimli

2
Bu doğru olabilir (dürüstçe bilmiyorum). Çekirdek gelişimi için (ve diğer birkaç alan için), ortalama programcılardan bahsetmiyoruz.

3
İnsanlar C -> C ++ 'ın bir süreklilik olduğunu unutur. Çok sık olarak, bu argümanlar iyi, modern C ++ ile C'yi karşılaştırır. Bir C programını alabilir ve nispeten kısa bir sürede bir C ++ derleyicisiyle derlemesini sağlayabilirsiniz ve tam olarak hızlı çalışacaktır. Modern bir C ++ özelliği "çok yavaş" ise kullanmayın. Hatta bunun gibi şeyleri de içerebilir iostream. "Çok yavaş" asla C ++ 'dan C kullanmak için iyi bir bahane değildir.
Gort the Robot

1

C ile zamanınızın çoğunu eldeki problemi ve çözümü nasıl kodlayacağınızı düşünerek geçirebilirsiniz. C ++ ile C ++ ve onun sayısız özellikleri, işlevleri ve belirsiz sözdizimi hakkında düşünürsünüz.

Ayrıca birçok C ++ mağazasında kodunuz, en son tasarım desenleri veya büyük tanrı Stroustrup'un en son anlaşılmaz açıklamaları tarafından büyülenen "moda polisi" tarafından izlenir. Güzel kod, çalışma kodundan daha değerli hale gelir, en son Boost şablonları kümesi için bir kullanım bulmak, iş için çalışan bir çözüm bulmaktan daha çok takdir edilir.

Deneyimlerim, C ++ 'ın tüm akıllı özellikleri ve OO saflığı için, düz C kodlamasının işi daha hızlı ve daha etkili hale getirmesidir.


0

C parçaları, C ++ parçaları için kullanılan C ++ derleyicisine hoş bir şekilde taşınabilir olmayabilir. Belki C kodu, C ++ derleyicisiyle kopan yollarla C derleyicisiyle aldatıcıdır.

Kaliteli bir C ++ derleyiciniz varsa, bir projede C ve C ++ 'ı karıştırmak için neredeyse hiçbir neden yoktur. Neredeyse.

Bunun nedeni, projenizin C kodunu diğer projelerle paylaşması, kodun C ++ olarak derlenmemesi ve bu kodun C ++ çatalını korumak istememenizdir.


-1

Ben geriye doğru olduğunu düşünüyorum - extern "C"blok C çağrı kuralları blok içindeki tüm fonksiyonlar için kullanılmasını sağlar. Yani C ++ 'dan değil C ++' dan saf C fonksiyonlarını çağırabilirsiniz. Ne olursa olsun, insanların hem C hem de C ++ 'ı kullanmasının nedeninin, C kullanarak birçok düşük seviyeli kütüphanenin yazılması ve kendi yazdığınızdan zaten var (ve muhtemelen hata ayıklanmış ve optimize edilmiş). OTOH, C ++, insanların çalışmayı tercih ettiği birçok güzel üst düzey özellik sunar, bu yüzden bunu geri kalanı için kullanırlar.


-2

Programlama dili olarak C'yi kullanan çeşitli gömülü platformlar vardır (elbette montaj dilini herhangi bir zamanda kullanma özgürlüğünüzdür)

'Seviye' için bir sistemin dahili SRAM ve ROM kaynak seviyesinden bahsediyorum.

Bu platformlar bazen kaynak kısıtlıdır (örneğin, bazı 8051 platformlarında yalnızca 128 bayt Kullanıcı SRAM'si bulunur).

RAM için çok az miktarda dinamik bellek tahsisini desteklemek anlamsızdır. (yeni / sil) hatta C'de malloc.

C'den C ++ 'ya ana gelişmeden biri Nesne yönelimli paradigmadır. C ++, daha büyük bellek alanına sahip yazılımlarda uygundur

ancak 32KB'ye kadar boyut sınırlaması olan gömülü bellenimde değil. (örneğin, 16 bit MCU plaformunda)

Genellikle C derleyicisinden daha karmaşık bir C ++ derleyicisine gerek yoktur. (en azından SDK sağlayıcıları bunu yapmak için uğraşmazlar).

Aslında 32 bit ARM7 platformu üzerinde bir C ++ derleyicisi bulamıyorum.

Sadece karmaşıklığa değmez

Bazı 8051 (8 bit): 1MB ROM, 128B RAM

TI MSP430 (16 Bit): 32KB ROM, 4KB RAM

ST Mikroelektronik ARM 32 bit Cortex ™ -M3 CPU Çekirdeği (STM32F103T4): 16 veya 32 Kbyte Flash bellek 6 veya 10 Kbyte SRAM


2
Bu, daha önce burada verilen diğer cevaplar için yeni bir şey değildir.
Martijn Pieters

ARM için 32 bit C ++ derleyicisi? İsterseniz, birkaç değişiklik yaptıktan sonra iOS için bir C ++ derleyicisi almak için LLVM'yi kaynaktan kendiniz derleyebilirsiniz.
Cole Johnson

-4

Birkaç olası neden görüyorum:

  • C, C ++ eşdeğerine kıyasla biraz daha verimlidir.
  • Kullandıkları bazı kütüphaneler C dilinde yazılmıştır.
  • C ile yazılmış Linux çekirdeğinin bazı kısımlarını kullanırlar.

Düzenlendi: Sonuç olarak, üçüncü argüman doğru değil (yorumlara bakın).


5
(1) C ++ halkı farklıdır. Nesnel olarak bunun böyle olması için hiçbir neden göremiyorum. (2) C ++, C kodunu iyi bir şekilde çağırabilir (geriye dönük uyumluluğun bütün noktasıdır ve extern "C").

1
MS Linux çekirdeğinin bazı kısımlarını kullanıyorsa ve Linux çekirdeği GPL ise, bu da Windows'un GPL olması gerektiği anlamına gelmez mi?
TomJ

1
@TomJ aslında bu yüzden Linux'a da birkaç bin satır bağışlamak zorunda kaldılar. + Sizce neden Linux geliştirmeyi destekliyorlar?
Pijusn

2
@Pius Onun amacı (ve sağ AFAIK), eğer Windows çekirdeğine GPL kodu bağlıysa, tüm çekirdek GPL olmalıdır (telif hakkı sahipleriyle ayrı bir anlaşma olmaması şartıyla).

@ delnan, detaylar hakkında emin değilim. Ben avukat değilim, bu konuda yorum yapamam. Ancak birkaç yıl önce bu konuda küçük bir skandal vardı. Emin değilim ama ben tüm çılgın şeyler hakkında ağ modülü olabilir düşünüyorum.
Pijusn

-4

Çünkü C tartışmasız C ++ 'dan daha iyi bir dildir. Ve kodun bir kısmı C ++ popüler olmadan önce yazıldığı ve insanların bunu değiştirmek için bir nedeni yoktu.

Ve C ++, bir çekirdeği kullanırken dikkatli olmazsanız kodunuzu kırabilecek birçok özelliğe sahip olduğundan.


C ++ dinamik kitaplıklar bekliyor? Dinamik bellek nedir?

4
-1 için [stuff] that C++ expects. C ++ neden C'den daha fazla yığın kullanıyor? Neden C ++, C'den daha fazla dll gerektirir? DOĞRU DEĞİL
Thomas Eding

1
Düzeltme: C ++ ile yazılmış kitaplıkları kaybedersiniz. C ++ veya C kullanıyorsanız, kare 1'e geri dönelim. Şablonları, sınıfları, yıkıcıları, sabitleri ve diğer her türlü iyiliği kullanabiliyorsanız neden kendinizi C işlevselliği ile sınırlandırın.
Thomas Eding

6
Ne? Şablonlar, istisnalar, nesneler (yapıcılar, yıkıcılar, aşırı yüklenmiş operatörler dahil, şimdi inşaatı taşıyor ve - pratikte? - diğer her şey), vb. . Standart kapsayıcılar varsayılan olarak yığın ayırmayı kullanır, ancak ayırıcıları özelleştirilebilir ve çekirdek çocuklar yine de kendi koleksiyonlarını ve bellek yönetimini yazarlar. -1

2
FYI: Downvote'umu kaldırdım çünkü cevabınızın şimdiye kadar aktif olarak zararlı olduğunu düşünmüyorum, ancak bunu da yararlı veya anlayışlı bulmuyorum.
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.