Gömülü geliştirme için C ++ yerine C kullanmak için herhangi bir neden var mı?


82

Soru

C ++ ve C89 donanımımda iki derleyicim var

Sınıflarla ancak polimorfizm olmadan (vtables'dan kaçınmak için) C ++ kullanmayı düşünüyorum. C ++ kullanmak istememin ana nedenleri:

  • Makro tanımları yerine "satır içi" işlevleri kullanmayı tercih ederim.
  • Önekler kodu karıştırdığından ad alanlarını kullanmak istiyorum.
  • C ++ 'ın temel olarak şablonlar ve ayrıntılı döküm nedeniyle biraz daha güvenli olduğunu görüyorum.
  • Aşırı yüklenmiş fonksiyonları ve yapıcıları gerçekten seviyorum (otomatik döküm için kullanılır).

Çok sınırlı donanım (4kb RAM) için geliştirirken C89'a bağlı kalmak için herhangi bir neden görüyor musunuz?

Sonuç

Cevaplarınız için teşekkür ederim, gerçekten yardımcı oldular!

Konuyu iyice düşündüm ve esas olarak C'ye bağlı kalacağım çünkü:

  1. C'de gerçek kodu tahmin etmek daha kolaydır ve eğer sadece 4kb ramınız varsa bu gerçekten önemlidir.
  2. Ekibim çoğunlukla C geliştiricilerinden oluşuyor, bu nedenle gelişmiş C ++ özellikleri sıklıkla kullanılmayacak.
  3. C derleyicimde (C89) satır içi işlevler bulmanın bir yolunu buldum.

Bu kadar çok iyi cevap verdiğiniz için bir cevabı kabul etmek zor. Ne yazık ki bir wiki yaratıp kabul edemiyorum, bu yüzden beni en çok düşündüren bir cevap seçeceğim.


11
Bir şey: her zaman hangi dilde yazdığınızı tam olarak açıklayın. "C / C ++" ile bir program yazmaya çalışmayın. Hangi dil özelliklerini kullanacağınızı ve hangilerini kullanmayacağınızı bilerek C veya C ++ ile yazın.
David Thornley


"Gömülü geliştirmeyi" tanımlayın
Marco van de Voort

@DavidThornley, gömülü vakalar için haklı olabilirsiniz, ancak Kamailio gibi yaygın endüstri açık kaynaklı uygulamalarını STL ile genişletmek istediğim yerde C ve C ++ kodunun ne kadar güzel bir şekilde birlikte oynandığına çok şaşırdım. STL ve C kodunun bu kullanımını resmi olarak teşvik ediyorum, çünkü neredeyse sıfır sorun yaratırken (C ++ 'da gömülü yapıların olmaması C ++' ya karşı korkunç bir suçtur ve en kısa sürede düzeltilmesi gerekir) ).
user2548100

Düşünmek için yiyecek, işte ZeroMQ tasarımcısı ve yazarının kod tabanını C yerine C ++ ile yazmaktan neden pişmanlık duyduğunu tartıştığı harika bir makale. Beklediğim gibi değil ve bu sayfanın başka bir yerinde bulunmayan nedenlerden dolayı. 250bpm.com/blog:4
user2548100

Yanıtlar:


48

C ++ üzerinde C kullanmanın iki nedeni:

  1. Çok sayıda gömülü işlemci için ya C ++ derleyicisi yoktur ya da bunun için fazladan ödeme yapmanız gerekir.
  2. Benim deneyimim, gömülü yazılım mühendislerinin önemli bir kısmının C ++ konusunda çok az deneyimi olduğu veya hiç olmadığı yönündedir - ya (1) nedeniyle ya da elektronik mühendisliği derecelerinde öğretilmeme eğilimindedir - ve bu nedenle bağlı kalmak daha iyi olacaktır. ne biliyorlar.

Ayrıca, orijinal soru ve birkaç yorum, 4 Kb RAM'den bahsediyor . Tipik bir gömülü işlemci için, kod depolandığı ve flash'tan çalıştırıldığı için RAM miktarı (çoğunlukla) kod boyutuyla ilgisizdir.

Kuşkusuz, kod depolama alanı miktarı akılda tutulması gereken bir konudur, ancak piyasada yeni, daha yetenekli işlemciler göründükçe, maliyete duyarlı projeler dışında hepsi için eskisinden daha az sorun olur.

Gömülü sistemlerle kullanım için bir C ++ alt kümesinin kullanımı hakkında: artık bir MISRA C ++ standardı var ve bu da bir göz atmaya değer olabilir.

DÜZENLEME: Gömülü sistemler için C ile C ++ arasında bir tartışmaya yol açan bu soruya da bakın .


2
Aşağıdaki daha uzun yanıtıma bakın: C ++, FLASH'a sabit veri koymayı çok zor hale getirme eğilimindedir.
jakobengblom2

3
C ++ yerine C kullanmak için potansiyel olarak iyi bir neden, C'nin standart ABI'sidir. Sadece eksiksizlik için.
Chris Lutz

66

Bir İçin Çok böyle RAM 4KB'den olarak kaynak kısıtlı hedefi, ben saf ANSI C uygulamasının içine kolayca taşınmış geri olamaz çaba taahhütte bulunmadan önce bazı örnekleri ile suları test ediyorum.

Gömülü C ++ çalışma grubu, dilin standart bir alt kümesini ve onunla uyumlu standart kitaplığın standart bir alt kümesini önerdi. Maalesef C User's Journal öldüğünde bu çabanın izini kaybettim. Görünüşe göre Wikipedia'da bir makale var ve komite hala var.

Gömülü bir ortamda, bellek ayırma konusunda gerçekten dikkatli olmalısınız. Bu bakımı güçlendirmek için, küresel operator new()olanı ve onun arkadaşlarını, kullanılmadığını bilmeniz için bağlantılı bile olmayan bir şeye tanımlamanız gerekebilir . Yerleştirmenew bir ahırda, evreli ve gecikme garantili tahsis şeması ile birlikte mantıklı kullanıldığında diğer taraftan muhtemel arkadaşın olmaktır.

Satır içi işlevler, ilk etapta gerçek işlevler olmaları gerekecek kadar büyük olmadıkça çok fazla soruna neden olmaz. Elbette makroların değiştirilmesinde de aynı sorun vardı.

Şablonlar da, somutlaştırılmaları yanlış çalışmadıkça bir soruna neden olmayabilir. Kullandığınız herhangi bir şablon için, yalnızca kullanmayı amaçladığınız örneklemelerin gerçekleştiğinden emin olmak için oluşturulan kodunuzu (bağlantı haritası yeterli ipucu içerebilir) denetleyin.

Ortaya çıkabilecek diğer bir sorun, hata ayıklayıcınızla uyumluluktur. Başka türlü kullanılabilen bir donanım hata ayıklayıcısının orijinal kaynak koduyla etkileşim için çok sınırlı desteğe sahip olması alışılmadık bir durum değildir. Derlemede etkili bir şekilde hata ayıklamanız gerekiyorsa, C ++ 'ın ilginç adı karıştırması göreve fazladan karışıklık ekleyebilir.

RTTI, dinamik yayınlar, çoklu kalıtım, ağır polimorfizm ve istisnaların tümü, kullanımları için bir miktar çalışma süresi maliyetiyle birlikte gelir. Kullanıldıklarında tüm programa mal olan bu özelliklerden birkaçı, diğerleri sadece onlara ihtiyaç duyan sınıfların ağırlığını arttırır. Farkı bilin ve en azından üstünkörü bir maliyet / fayda analizi hakkında tam bilgi sahibi olarak gelişmiş özellikleri akıllıca seçin.

Küçük bir gömülü ortamda ya doğrudan gerçek zamanlı bir çekirdeğe bağlanacak ya da doğrudan donanım üzerinde çalışacaksınız. Her iki durumda da, çalışma zamanı başlangıç ​​kodunuzun C ++ 'ya özgü başlangıç ​​işlerini doğru şekilde işlediğinden emin olmanız gerekir. Bu, doğru bağlayıcı seçeneklerini kullandığınızdan emin olmak kadar basit olabilir, ancak sıfırlama giriş noktasında güç kaynağı üzerinde doğrudan kontrole sahip olmak yaygın olduğundan, her şeyi yaptığından emin olmak için bunu denetlemeniz gerekebilir. Örneğin, üzerinde çalıştığım bir ColdFire platformunda, geliştirici araçları C ++ başlatıcılarının bulunduğu ancak yorum yapan bir CRT0.S modülüyle birlikte geldi. Kutudan çıkardığım gibi kullansaydım, kurucuları hiç çalışmayan küresel nesneler beni şaşırtacaktı.

Ayrıca, gömülü bir ortamda, donanım aygıtlarını kullanılmadan önce başlatmak gerekir ve işletim sistemi ve önyükleyici yoksa, bunu yapan kodunuzdur. Global nesneler için kurucuların çağrılmadan önce çalıştırıldığını hatırlamanız gerekecek, bu main()nedenle yerel CRT0.S'nizi (veya eşdeğerini) global kurucuların kendileri çağrılmadan önce donanım başlatmayı yapmak için değiştirmeniz gerekecektir . Açıkçası, tepesi main()çok geç.


1
Bunun benim verebileceğimden daha fazla olumlu oyu olması gerekiyor! Mükemmel cevap.
Harper Shelby

+1, harika yanıt. Ancak, gerçekten endişelenmeniz gereken tek şablon somutlaştırmanın (nispeten nadir) özyinelemeli tür olduğunu düşünüyorum - "düzenli" özyinelemeli olmayan tür için, somutlaştırma, yine de elle yazmış olacağınız koda karşılık gelir.
j_random_hacker

2
@j_random_hacker, doğru. Ancak, şablonların alışkanlığı, kullanım noktasında uygun tip zorlamasının engellemiş olabileceği ikinci (veya üçüncü) bir örnekleme göründüğünde ara sıra sürprizlere yol açabilir. Sadece dikkat edilmesi gereken bir şey.
RBerteig

@RBerteig: İyi bir nokta, şablonlar daha az tür zorlama olasılığına izin veriyor => muhtemelen şablon olmayan koddan daha fazla farklı somutlaştırma üretiliyor.
j_random_hacker

26

Hayır. Sorunlara neden olabilecek C ++ dil özelliklerinden herhangi biri (çalışma zamanı çok biçimliliği, RTTI, vb.), Gömülü geliştirme yapılırken önlenebilir. Gömülü C ++ geliştiricilerinden oluşan bir topluluk var (eski C / C ++ Users 'Journal'da C ++ kullanan yerleşik geliştiricilerin sütunlarını okuduğumu hatırlıyorum) ve seçim bu kadar kötü olsaydı çok sesli olacağını hayal edemiyorum.


20

C ++ Performansına Teknik Rapor şey bu tür için büyük bir kılavuzdur. Gömülü programlama sorunlarıyla ilgili bir bölümü olduğunu unutmayın!

Ayrıca ++, yanıtlarda Gömülü C ++ 'dan bahsedildiğinde. Standart zevklerime göre% 100 değil, ancak C ++ 'nın hangi bölümlerini bırakabileceğinize karar verirken iyi bir referans kaynağıdır.

Küçük platformlar için programlama yaparken, istisnaları ve RTTI'yi devre dışı bıraktık, sanal kalıtımdan kaçındık ve etrafta yatan sanal işlevlerin sayısına çok dikkat ettik.

Arkadaşınız bağlayıcı harita olsa da: sık sık kontrol edin ve kod kaynaklarını ve statik bellek şişkinliğini çabucak fark edeceksiniz.

Bundan sonra, standart dinamik bellek kullanımıyla ilgili hususlar geçerlidir: Bahsettiğiniz gibi kısıtlı bir ortamda, dinamik ayırmaları hiç kullanmak istemeyebilirsiniz. Bazen küçük dinamik allocs için bellek havuzlarından veya bir bloğu önceden tahsis edip her şeyi daha sonra attığınız "çerçeve tabanlı" ayırmadan kurtulabilirsiniz.


16

C ++ derleyicisini kullanmanızı, ancak C ++ 'ya özgü özelliklerin kullanımınızı sınırlamanızı öneririm. C ++ 'da C gibi programlayabilirsiniz (C ++ yapılırken C çalışma zamanı dahil edilir, ancak çoğu gömülü uygulamada zaten standart kitaplığı kullanmazsınız).

Devam edebilir ve C ++ sınıflarını vb. Kullanabilirsiniz.

  • Sanal işlev kullanımınızı sınırlandırın (söylediğiniz gibi)
  • Şablon kullanımınızı sınırlayın
  • Gömülü bir platform için, yeni operatörü geçersiz kılmak ve / veya bellek ayırma için yeni yerleşimi kullanmak isteyeceksiniz.

8
Elbette, zaten temelde C yazıyorsanız, onu resmileştirebilirsiniz.
Chuck

6
Şablonların kullanımını neden sınırlandırıyorsunuz? Şablon işlevlerinin gömülü sistemlerde, örneğin döngüleri açmak için gerçekten yararlı olabileceğini düşündüm.
Piotr Czapla

1
Hala şablonları kullanabilirsiniz, ancak çıktı ikili dosyasının boyutunu hızla artırabildikleri için bunlara çok dikkat ederim. Elbette, kodunuz doğrudan ROM veya benzerinden çalışıyorsa ve yedeklemek için ROM alanınız varsa, o zaman elbette, ancak bunun dışında şablonlarla ne yaptığınıza dikkat etmeniz gerekir (her şablon örneği temelde tüm şablon kodunun tekrar kopyalanmasıdır. en kötü durumda nihai yürütülebilir dosyada).
arke

14

Bir aygıt yazılımı / gömülü sistem mühendisi olarak, size C'nin neden hala C ++ 'ya göre 1 numaralı seçim olduğunu söyleyebilirim ve evet, her ikisinde de akıcıyım.

1) Geliştirdiğimiz bazı hedefler, hem kod hem de veri için 64kB RAM'e sahiptir, bu nedenle her baytın sayıldığından emin olmalısınız ve evet, bana 2 saate mal olan 4 bayt tasarruf etmek için kod optimizasyonu ile uğraştım ve bu 2008.

2) Boyut sınırlaması nedeniyle, her C kütüphanesi işlevi, son koda izin verilmeden önce gözden geçirilir, bu nedenle insanların bölme (donanım bölücü yok, bu nedenle büyük bir kitaplığa ihtiyaç vardır), malloc (çünkü yığın yok , tüm bellek 512 bayt yığınındaki veri arabelleğinden ayrılır ve kod gözden geçirilmelidir) veya büyük ceza gerektiren diğer nesne yönelimli uygulamalar. Unutmayın, kullandığınız her kitaplık işlevi sayılır.

3) Yer paylaşımı terimini hiç duydunuz mu? o kadar az kod alanınız var ki, bazen bir şeyleri başka bir kod setiyle değiştirmek zorunda kalıyorsunuz. Bir kitaplık işlevini çağırırsanız, kitaplık işlevi yerleşik olmalıdır. Bunu yalnızca bir kaplama işlevinde kullanırsanız, çok fazla nesne yönelimli yönteme güvenerek çok fazla alan harcarsınız. Bu nedenle, C ++ 'ın kabul edilmesini, herhangi bir C kütüphanesi işlevini varsaymayın.

4) Sınırlı donanım tasarımı (yani belirli bir şekilde bağlanan bir ECC motoru) nedeniyle veya bir donanım hatasıyla başa çıkmak için döküm ve hatta paketleme (hizalanmamış veri yapısının kelime sınırını geçtiği yerlerde) gereklidir. Açıkça çok fazla şey varsayamazsınız, öyleyse nesne neden onu çok fazla yönlendirsin?

5) En kötü durum senaryosu: Nesne yönelimli yöntemlerden bazılarının ortadan kaldırılması, patlayabilen kaynakları kullanmadan önce geliştirmeyi düşünmeye zorlayacaktır (yani bir veri arabelleğinden ziyade bir yığına 512 bayt ayırmak) ve bu olası en kötü durum senaryosunun bazılarını önleyecektir. tüm kod yolu için test edilmez veya tamamen ortadan kaldırılmaz.

6) Donanımı yazılımdan uzak tutmak ve kodu olabildiğince taşınabilir ve simülasyon dostu hale getirmek için çok fazla soyutlama kullanıyoruz. Donanım erişimi, farklı platformlar arasında koşullu olarak derlenen bir makro veya satır içi işlevle sarılmalıdır, veri türü hedefe özel değil bayt boyutu olarak dönüştürülmelidir, doğrudan işaretçi kullanımına izin verilmez (çünkü bazı platformlar bellek eşlemeli G / Ç'nin veri belleğiyle aynı) vb.

Daha fazlasını düşünebilirim, ama sen anladın. Biz bellenim adamlarının nesneye yönelik eğitimi var, ancak gömülü sistemin görevi donanım odaklı ve düşük seviyeli olabilir, bu yüksek seviye veya doğası gereği soyutlanamaz.

BTW, bulunduğum her ürün yazılımı işi kaynak kontrolünü kullanıyor, bu fikri nereden aldığınızı bilmiyorum.

-SanDisk'ten bir aygıt yazılımı uzmanı.


90'lı yılların başında, kaplama çok popüler bir teknikti (en azından DOS dünyasında)
psihodelia

İyi puanlar Shing. C ++, işlevselliğin sınırlı olduğu ve kaynakların daha da sınırlı olduğu projelerde telefon kulübesinde bir Sumo güreşçisi gibi hissediyor.

4
Bu cevabın çok öznel olduğuna ve somut bir mantık sağlamadığına inanıyorum.
Venemo

1
C ++ mutlaka "nesne yönelimli" anlamına gelmez.
Martin Bonner Monica'yı

1
Gömülü sistemin görevinin doğası gereği soyutlanabilir olmadığı doğru değil. 6. noktada kendiniz söylediniz: "hw'yi sw'den uzak tutmak ve kodu mümkün olduğunca taşınabilir hale getirmek için çok fazla soyutlama kullanıyoruz" :-) BTW: "soyutlama" mutlaka "çok biçimlilik" anlamına gelmez.
Daniele Pallastrelli

9

Kişisel tercihim C çünkü:

  • Her kod satırının ne yaptığını (ve maliyetini) biliyorum
  • C ++ 'ı her kod satırının ne yaptığını (ve maliyetini) bilecek kadar iyi bilmiyorum

İnsanlar bunu neden söylüyor? Sen yok sen asm çıkışını kontrol sürece C'nin her satırı ne yaptığını biliyorum. Aynısı C ++ için de geçerli.

Örneğin, bu masum ifade ne üretir:

a[i] = b[j] * c[k];

Oldukça masum görünüyor, ancak gcc tabanlı bir derleyici bu asm'yi 8 bitlik bir mikro için üretir

CLRF 0x1f, ACCESS
RLCF 0xfdb, W, ACCESS
ANDLW 0xfe
RLCF 0x1f, F, ACCESS
MOVWF 0x1e, ACCESS
MOVLW 0xf9
MOVF 0xfdb, W, ACCESS
ADDWF 0x1e, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfa
MOVF 0xfdb, W, ACCESS
ADDWFC 0x1f, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0xfee, 0x1c
NOP
MOVFF 0xfef, 0x1d
NOP
MOVLW 0x1
CLRF 0x1b, ACCESS
RLCF 0xfdb, W, ACCESS
ANDLW 0xfe
RLCF 0x1b, F, ACCESS
MOVWF 0x1a, ACCESS
MOVLW 0xfb
MOVF 0xfdb, W, ACCESS
ADDWF 0x1a, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfc
MOVF 0xfdb, W, ACCESS
ADDWFC 0x1b, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0xfee, 0x18
NOP
MOVFF 0xfef, 0x19
NOP
MOVFF 0x18, 0x8
NOP
MOVFF 0x19, 0x9
NOP
MOVFF 0x1c, 0xd
NOP
MOVFF 0x1d, 0xe
NOP
CALL 0x2142, 0
NOP
MOVFF 0x6, 0x16
NOP
MOVFF 0x7, 0x17
NOP
CLRF 0x15, ACCESS
RLCF 0xfdf, W, ACCESS
ANDLW 0xfe
RLCF 0x15, F, ACCESS
MOVWF 0x14, ACCESS
MOVLW 0xfd
MOVF 0xfdb, W, ACCESS
ADDWF 0x14, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfe
MOVF 0xfdb, W, ACCESS
ADDWFC 0x15, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0x16, 0xfee
NOP
MOVFF 0x17, 0xfed
NOP

Üretilen talimatların sayısı büyük ölçüde şunlara bağlıdır:

  • A, b ve c boyutları.
  • bu işaretçiler yığında mı depolanıyor yoksa genel mi
  • i, j ve k yığında mı yoksa global mi

Bu, özellikle işlemcilerin C'yi işleyecek şekilde ayarlanmadığı küçük gömülü dünyada doğrudur. Bu yüzden cevabım, asm çıktısını her zaman incelemediğiniz sürece C ve C ++ 'nın birbirleri kadar kötü olduğu olacaktır, bu durumda bunlar birbirleri kadar iyidir.

Hugo


2
Ayrıca çarpma işlevini çağıran her şeyin ortasında bir çağrı talimatı olduğuna dikkat edin. Tüm bu kodlar, çarpma talimatı bile değil!
Rocketmagnet

Mikroya aşina olan biri, tipik olarak C kodunun her bir bölümünü tek başına işlemenin basit bir yolunu bilir ve iyi bir derleyici bundan daha kötü bir kod üretmemelidir. Yukarıdaki ifadenin verimli bir şekilde işlenmesinin tek yolu, birinin bir C derleyicisi için uygun olmayabilecek varsayımlarda bulunmasıdır.
supercat

8

Bazı insanların daha basit ve dolayısıyla üretilecek gerçek kodu tahmin etmenin daha kolay olması nedeniyle gömülü çalışma için C'yi tercih ettiğini duydum.

Ben şahsen C tarzı C ++ yazmanın (tür güvenliği için şablonlar kullanmak) size birçok avantaj sağlayacağını düşünürdüm ve bunu yapmamak için gerçek bir neden göremiyorum.


+1, şeffaflık her zaman önemlidir ve muhtemelen kısıtlı hata ayıklama araçlarıyla (muhtemelen) kısıtlı bir ortam için daha da önemlidir.
j_random_hacker

7

C ++ yerine C kullanmak için bir neden göremiyorum. C ile ne yaparsanız yapın, C ++ ile de yapabilirsiniz. VMT'nin ek yüklerinden kaçınmak istiyorsanız, sanal yöntemler ve çok biçimlilik kullanmayın.

Bununla birlikte, C ++ ek yükü olmadan çok kullanışlı bazı deyimler sağlayabilir. Favorilerimden biri RAII. Sınıflar hafıza veya performans açısından pahalı değildir ...


6

IAR Workbench üzerinde ARM7 gömülü platform için bazı kodlar yazdım. Derleme zamanı optimizasyonu ve yol tahmini yapmak için şablonlara güvenmenizi şiddetle tavsiye ederim. Veba gibi dinamik yayınlardan kaçının. Andrei Alexandrescu'nun Modern C ++ tasarımı kitabında belirtildiği gibi özellikleri / politikaları kendi yararınıza kullanın .

Biliyorum, öğrenmesi zor olabilir ama eminim ki ürününüz bu yaklaşımdan fayda sağlayacaktır.


5

İyi bir neden ve bazen tek neden, belirli gömülü sistem için hala C ++ derleyicisinin olmamasıdır. Örneğin Microchip PIC mikro denetleyiciler için durum budur. Yazmaları çok kolaydır ve ücretsiz bir C derleyicisine sahiptirler (aslında, C'nin hafif bir varyantı), ancak görünürde C ++ derleyicisi yoktur.


1
Comeau Computing ( comeaucomputing.com ) C'ye derleyen bir C ++ derleyicisi satıyor
Thomas L Holaday

3
Eww. O site kusmak istedi.
13'te shoosh

@shoosh: Evet, site tasarımı berbat. Bununla birlikte, derleyicinin kendisi, en azından standart uygunluk açısından bu alanda bir lider olarak kabul edilir (performans hakkında hiçbir bilgim yok).
j_random_hacker

Bu web sitesi bana yaşayan, nefes alan ve ÇOK öfkeli bir meyve salatası içinde hapsolmuş gibi hissettiriyor.
Tim Post

5

4K ram ile kısıtlanmış bir sistem için, C ++ yerine C kullanırım, sırf olup biten her şeyi görebilmeniz için. C ++ ile olan şey, koda bakmaktan çok daha fazla kaynak (hem CPU hem de bellek) kullanmanın çok kolay olmasıdır. (Oh, bunu yapmak için başka bir BlerfObject oluşturacağım ... hoppala! Bellek yetersiz!)

Bunu daha önce de belirtildiği gibi C ++ ile yapabilirsiniz (RTTI yok, vtables yok, vb.), Ancak C ++ kullanımınızın C'deki eşdeğerini yaptığınız gibi sizden uzaklaşmamasını sağlamak için çok zaman harcayacaksınız. .


2
Son cümlenin doğru ama ilgisiz çünkü C ++, C'ye göre dengeyi değiştiren (olabilecek) başka avantajlar sunuyor. Piotr, bu (sıfır maliyetli) avantajların bazılarından daha önce bahsetmiştir.
Konrad Rudolph

5

İnsan zihni, karmaşıklığı olabildiğince değerlendirerek ve ardından neye odaklanılması gerektiğine karar vererek ve geri kalanını atarak veya değerini düşürerek başa çıkar. Pazarlamada markalaşmanın ve büyük ölçüde simgelerin arkasındaki tüm temel budur.

Bu eğilimle mücadele etmek için C'yi C ++ 'ya tercih ederim, çünkü sizi kodunuz ve donanımla nasıl daha yakından etkileşime girdiğini düşünmeye zorluyor - durmaksızın yakın.

Uzun deneyimlerime dayanarak, C'nin sizi sorunlara daha iyi çözümler bulmaya zorladığına inanıyorum, kısmen yolunuzdan çekilerek ve sizi bir kısıtlamayı tatmin etmek için çok fazla zaman harcamaya zorlamayın. veya "örtülerin altında" neler olduğunu anlamak.

Bu bağlamda, C gibi düşük seviyeli diller, donanıma odaklanmak ve iyi veri yapısı / algoritma paketleri oluşturmak için çok zaman harcarken, yüksek seviyeli diller, orada neler olup bittiğini merak etmek için çok fazla zaman harcamanızı sağlar. ve neden özel bağlamınızda ve ortamınızda tamamen makul bir şey yapamıyorsunuz? Derleyicinizi teslim etmek için yenmek (güçlü yazım en kötü suçtur) zamanın verimli kullanımı DEĞİLDİR.

Muhtemelen programcı kalıbına iyi uyuyorum - kontrolü seviyorum. Benim görüşüme göre, bu bir programcı için bir kişilik kusuru değil. Kontrol, yapmamız için para aldığımız şeydir. Daha spesifik olarak, KUSURSUZ bir şekilde kontrol edin. C size C ++ 'dan çok daha fazla kontrol sağlar.


ZeroMQ'nun yazarı Martin Sistrik, neden şimdi ZeroMQ'yu C ++ yerine C ile yazmayı dilediğini tartışırken neredeyse aynı noktaya değindi. Check it out 250bpm.com/blog:8
user2548100

3

Kişisel olarak 4kb bellek ile C ++ 'dan o kadar fazla mesafe alamadığınızı söyleyebilirim, bu yüzden iş için en iyi derleyici / çalışma zamanı kombinasyonu gibi görünen birini seçin, çünkü dil muhtemelen çok fazla önemli olmayacak.

Kütüphane de önemli olduğundan, her şeyin dil ile ilgili olmadığını unutmayın. Genellikle C kitaplarının minimum boyutu biraz daha küçüktür, ancak gömülü geliştirmeyi hedefleyen bir C ++ kitaplığının azaltıldığını hayal edebiliyorum, bu yüzden test ettiğinizden emin olun.


2

C taşınabilirlik konusunda kazanır - çünkü dil spesifikasyonunda daha az belirsizdir; bu nedenle farklı derleyiciler vb. arasında çok daha iyi taşınabilirlik ve esneklik sunar (daha az baş ağrısı).

Bir ihtiyacı karşılamak için C ++ özelliklerinden yararlanmayacaksanız, C ile devam edin.


Dilin açık olup olmadığı, kişinin onu daha önce sağduyu olarak kabul edilen şeyleri belirleme olarak görüp görmediğine bağlıdır, ancak günümüzde öyle değildir [örneğin, 32-bit sessiz-sarmalayan iki tamamlayıcı donanım için bir derleyici unsigned mul(unsigned short x, unsigned short y) { return x*y;}yok gibi bir şey işlemelidir. ürün 2147483647'yi aşsa bile yan etkiler veya void get_float_bits(float *fp, uint32_t n) { *(uint32_t)fp = n; }muhtemelen a'nın değerini değiştirdiğini düşünmesi gerekir float].
supercat

2

Çok sınırlı donanım (4kb RAM) için geliştirirken C89'a bağlı kalmak için herhangi bir neden görüyor musunuz?

Kişisel olarak, gömülü uygulamalar söz konusu olduğunda (Gömülü dediğimde, bugün winCE, iPhone vb. Şişirilmiş gömülü cihazları kastetmiyorum). Kaynak sınırlı cihazlar demek istiyorum. C ++ ile de epey çalışmış olsam da C'yi tercih ediyorum.

Örneğin, bahsettiğiniz cihazda 4kb var RAM var, bu nedenle C ++ 'ı dikkate almam. Elbette, C ++ kullanarak küçük bir şey tasarlayabilir ve diğer yayınların önerdiği gibi uygulamanızda kullanımınızı sınırlayabilirsiniz, ancak C ++ potansiyel olarak uygulamanızı kapaklar altında karmaşıklaştırabilir / şişirebilir.

Statik olarak bağlanacak mısınız? C ++ ve c kullanarak statik bir kukla uygulamayı karşılaştırmak isteyebilirsiniz. Bu, bunun yerine C'yi düşünmenize neden olabilir. Öte yandan, bellek gereksinimleriniz dahilinde bir C ++ uygulaması oluşturabiliyorsanız, bunun için gidin.

IMHO, Genel olarak gömülü uygulamalarda olup biten her şeyi bilmek isterim. Bellek / sistem kaynaklarını kim kullanıyor, ne kadar ve neden? Onları ne zaman serbest bırakırlar?

X miktarda kaynak, cpu, bellek vb. Olan bir hedef için geliştirme yaparken, bu kaynakları kullanmanın alt tarafında kalmaya çalışıyorum çünkü gelecekte hangi gereksinimlerin ortaya çıkacağını asla bilemiyorsunuz ve böylece projeye daha fazla kod eklemiş oluyorsunuz. basit ve küçük bir uygulama olması gerekiyordu, ancak çok daha büyük hale geliyor.


1
İki derleyiciyi kesinlikle karşılaştıracağım. (btw. İşletim sistemi olmadığı için dinamik olarak bağlantı kuramıyorum)
Piotr Czapla

2

Seçimim genellikle, kullanmaya karar verdiğimiz, cihazın ne yapması gerektiğine göre seçilen C kütüphanesi tarafından belirlenir. Yani, 9/10 kere .. uclibc veya newlib ve C olur. Kullandığımız çekirdek de bu konuda büyük bir etkiye sahip veya kendi çekirdeğimizi yazıyorsak.

Aynı zamanda bir ortak zemin seçimi. Çoğu iyi C programcısının C ++ kullanmakta bir sorunu yoktur (birçok kişi onu kullandıklarından şikayet etse de) .. ama ben bunun tersini doğru bulmadım (deneyimlerime göre).

Üzerinde çalıştığımız (temelden çekirdek içeren) bir projede, çoğu şey C'de yapılır, ancak C ++ 'da küçük bir ağ yığını uygulanmıştır, çünkü ağları C ++ kullanarak uygulamak daha kolay ve daha az sorunluydu.

Sonuç olarak, cihaz ya çalışacak ve kabul testlerini geçecek ya da geçmeyecektir. Xx yığınında foo ve z dilini kullanarak yy yığın kısıtlamalarını uygulayabilirseniz, bunun için gidin, sizi daha üretken yapan her şeyi kullanın.

Kişisel tercihim C çünkü:

  • Her kod satırının ne yaptığını (ve maliyetini) biliyorum
  • C ++ 'ı her kod satırının ne yaptığını (ve maliyetini) bilecek kadar iyi bilmiyorum

Evet, C ++ konusunda rahatım, ancak bunu standart C kadar iyi bilmiyorum.

Şimdi bunun tersini söyleyebiliyorsanız, peki, bildiklerinizi kullanın :) Çalışıyorsa, testleri geçerse vb .. sorun nedir?


2
> # Her kod satırının ne yaptığını (ve maliyetini) biliyorum, derleyiciler yazmış olsaydım, bundan o kadar emin olmazdım ... iyi bir C derleyicisi kodunuza oldukça şaşırtıcı şeyler yapabilir, bir şeyler. Satır satır derlemez.
jakobengblom2

@ jakobengblom2: Gömülü geliştirme için, tutarlı performansa sahip olmak genellikle maksimum performansa sahip olmaktan daha önemlidir. Bir kod parçasının zamanlama gereksinimlerini karşılayıp karşılamayacağını belirlemeye çalışıyorsanız, bir derleyicinin gerçek bellenimde çalışmayacak "test" belleniminde kullanılabilecek optimizasyonları kullanması pek de yararlı olmayacaktır.
supercat

2

Ne kadar ROM / FLASH'ınız var?

4kB RAM, gerçek kodu ve statik verileri depolamak için yüzlerce kilobayt FLASH olduğu anlamına gelebilir. Bu boyuttaki RAM, yalnızca değişkenler içindir ve bunlara dikkat ederseniz, kod satırları açısından oldukça büyük bir programı belleğe sığdırabilirsiniz.

Bununla birlikte, C ++, nesneler için çalışma zamanı oluşturma kuralları nedeniyle FLASH'a kod ve veri koymayı daha zor hale getirme eğilimindedir. C'de, sabit bir yapı FLASH belleğe kolayca yerleştirilebilir ve bir donanım sabit nesnesi olarak erişilebilir. C ++ 'da sabit bir nesne, derleyicinin kurucuyu derleme zamanında değerlendirmesini gerektirir, ki bu hala bir C ++ derleyicisinin yapabileceğinin ötesinde bir şeydir (teorik olarak bunu yapabilirsiniz, ancak pratikte yapmak çok zordur) .

Yani "küçük RAM", "büyük FLASH" türü bir ortamda C ile her gün giderdim. Sınıfa dayalı olmayan kod için güzel C ++ özelliklerinin çoğuna sahip olan iyi bir ara seçim olan C99 olduğunu unutmayın.


3
C'deki Flash belleğe konan aynı yapının C ++ 'da Flash'ta da bitmemesinin herhangi bir nedeni var mı? Sen yok olması C ++ da yapı için bir kurucu ekleyin.
jalf

1

Genel olarak hayır. C ++ süper bir C kümesidir. Bu özellikle yeni projeler için geçerli olacaktır.

Cpu süresi ve bellek ayak izi açısından pahalı olabilecek C ++ yapılarından kaçınmak için doğru yoldasınız.

Çok biçimlilik gibi bazı şeylerin çok değerli olabileceğini unutmayın - bunlar aslında işlev işaretçileridir. Onlara ihtiyacınız olduğunu fark ederseniz, akıllıca kullanın.

Ayrıca, iyi (iyi tasarlanmış) istisna yönetimi, yerleşik uygulamanızı geleneksel hata kodlarıyla işleyen bir uygulamadan daha güvenilir hale getirebilir.


2
C ++, kesin olarak C'nin katı bir üst kümesi değildir, ancak bu belirli ayrıntı bu bağlamda özellikle önemli değildir.
Arafangion

1

Bellek ayırma sorunu için, Quantum Platform'u ve başlatma anında ihtiyacınız olan her şeyi tahsis ettiği için durum makinesi yaklaşımını kullanmanızı tavsiye edebilirim. Ayrıca çekişme sorunlarını hafifletmeye yardımcı olur.

Bu ürün hem C hem de C ++ üzerinde çalışır.


1

Bazıları, C derleyicilerinin çok daha verimli kod üretebileceğini, çünkü gelişmiş C ++ özelliklerini desteklemeleri gerekmediğini ve bu nedenle optimizasyonlarında daha agresif olabileceğini söylüyor.

Elbette, bu durumda iki özel derleyiciyi test etmek isteyebilirsiniz.


1
Alakalı: restrict anahtar sözcüğü, bildiğim kadarıyla C ++ 'da eksik olan tek optimizasyonla ilgili C yapısını (ayrıca C ++ 11).
Johan Lundberg

1

C IMHO'yu tercih etmenin tek nedeni, platformunuz için C ++ derleyicisinin iyi durumda olmamasıdır (hatalı, zayıf optimizasyon, vb.).


Peki ya bellek / kaynak kullanımı?
Steve Lazaridis

Ne olacak? Kodun gömülü sistemlerde kimsenin yapmadığı RTTI kullanması dışında, bir C ++ derleyicisinin bir C koddan daha az verimli kod üretmesi için hiçbir neden yoktur.
Nemanja Trifunovic


1

C99'da satır içi var. Belki ctor'ları seviyorsunuz, ama dansçıları doğru bulma işi karmaşık olabilir. C'yi kullanmamanın tek nedeni ad alanları ise, gerçekten C89'a bağlı kalırım. Bunun nedeni, onu biraz farklı bir gömülü platforma taşımak isteyebilmenizdir. Daha sonra aynı kod üzerinde C ++ ile yazmaya başlayabilirsiniz. Ancak aşağıdakilere dikkat edin, burada C ++ C'nin bir üst kümesi DEĞİLDİR, biliyorum bir C89 derleyiciniz olduğunu söylediniz, ancak yine de C99 ile bu C ++ karşılaştırması yapıyor, çünkü örneğin ilk öğe K & R'den beri herhangi bir C için doğrudur.

sizeof 'a' > 1, C ++ 'da değil. C'de VLA değişken uzunluklu dizileriniz var. Örnek: func (int i) {int a [i] . C'de VAM değişken dizisi üyeleriniz var. Örnek: struct {int b; int m [];} .


1
Hayır. C de (sizeof 'a') == sizeof (int) 'e sahip olduğunuzu belirtmek istiyorum. C ++ sen varken o 1 == sizeof 'a'
hept

1
"İnt * a; ...; a = (int *) malloc (size * sizeof (int));" C ve C ++ 'da çalışan belleği ayırmanın yoludur ve ikisinde de kullanılmamalıdır. "A = malloc (size * sizeof (int));" veya "vektör <int> a (boyut);" hatta "int * a = new int [size];" yerine.
David Thornley

1
Dansçılar hakkındaki fikrini anlamıyorum. Onlarla ilgili tüm nokta, kodunuzun geri kalanını çok daha az dağınık hale getirmeleridir .
jalf

1
+1, bu gönderinin neden bu kadar kötü bir şöhrete sahip olduğundan emin değilim. Ancak jalf ile aynı fikirdeyim, yıkıcılar doğru (RAII) şekilde kullanıldığında kodu büyük ölçüde basitleştirir . ("Perde arkasında çalıştıklarını" söyleyebilirsiniz, ancak yine de yalnızca doğru kodun manuel olarak yapacağı şeyleri yapıyorlar.)
j_random_hacker

1
Sanırım bahsettiğim şeyler soruyla çok alakalı. Ayrıca dişçilerin zor olabileceğine dair ifademe sadık kalıyorum ve nedeni tam olarak bunun otomatik olarak gerçekleşmesidir. Eksi puanlarım var - bu gerçekten iğrenç. Sanırım "EVET, C ++ BÜYÜK GİTMEK" demediğim için.
hept

1

Derleyiciye bağlıdır.

Gömülü derleyicilerin tümü tüm C ++ 'yı uygulamaz ve yapsalar bile, kod şişkinliğini önleme konusunda iyi olmayabilirler (bu, şablonlar için her zaman bir risktir). Birkaç küçük programla test edin, herhangi bir sorunla karşılaşıp karşılaşmadığınızı görün.

Ancak iyi bir derleyici verildiğinde , hayır, C ++ kullanmamak için bir neden yok.


1

Sadece "SINIRSIZ" kaynaklara sahip bir sistem olmadığını söylemek istiyorum. Bu dünyadaki her şey sınırlıdır ve ASM, C, JAVA veya JavaScript olsun, HER uygulama kaynak kullanımını dikkate almalıdır. "Emin olmak için" birkaç Mbs ayıran aptallar iPhone 7, Pixel ve diğer cihazları son derece çekici kılıyor. 4kb veya 40 Gb'ye sahip olmanız fark etmez.

Ancak başka bir taraftan kaynak israfına karşı çıkmak - bu kaynakları kurtarmak için gereken bir zamandır. C ++ 'ı kullanmak yerine birkaç tik ve birkaç bayt kaydetmek için basit bir şey yazmak için 1 hafta fazladan sürüyorsa, zaten uygulanmış, test edilmiş ve dağıtılmış. Neden uğraşıyorsun? USB hub satın almak gibi. evet kendiniz yapabilirsiniz ama daha iyi olacak mı? daha güvenilir? zamanını sayarsan daha mı ucuz?

Sadece bir yan düşünce - prizinizden gelen güç bile sınırsız değildir. Nereden geldiğini araştırmaya çalışın ve çoğunlukla bir şeyler yakmaktan olduğunu göreceksiniz. Enerji ve malzeme yasası hala geçerlidir: hiçbir malzeme veya enerji görünmez veya kaybolmaz, aksine dönüşür.


0

Gömülü geliştirme için ISO C ++ 'nın nasıl kullanılacağına dair bir örnek buldum, bu, C ++ veya C'yi her kullandığında karar veren biri için ilginç olabilir.

Bjarne Stroustrup tarafından ana sayfasında sağlandı :

ISO C ++ 'nın ciddi gömülü sistem programlamasında nasıl kullanılabileceğine bir göz atmak için JSF hava aracı C ++ kodlama standartlarına bakın .


Uçan şeyler, gigabayt RAM'li PPC işlemcilere sahip olma eğilimindedir. Ortalama kaynak kısıtlı gömülü sisteminiz değil.
jakobengblom2

0

Sorunun farklı bir yönüne farklı yanıt gönderimi:

"malloc"

Daha önceki bazı yanıtlar bunun hakkında biraz konuşuyor. Neden bu aramanın var olduğunu düşünüyorsun? Gerçekten küçük bir platform için, malloc kullanılamaz veya kesinlikle isteğe bağlı olma eğilimindedir. Dinamik bellek tahsisini uygulamak, sisteminizin altında bir RTOS'a sahip olduğunuzda anlamlı olma eğilimindedir - ancak o zamana kadar, tamamen tehlikelidir.

Onsuz çok uzağa gidebilirsin. Yerel değişkenler için uygun bir yığını bile olmayan tüm eski FORTRAN programlarını bir düşünün ...


0

Dünya çapında çok sayıda farklı denetleyici üreticisi vardır ve bunların tasarımlarına ve yapılandırmak için kullanılması gereken talimat setlerine baktığınızda birçok sorunla karşılaşabilirsiniz. Assembly dilinin temel dezavantajı makineye / mimariye bağlı olmasıdır. Bir geliştiriciden, farklı denetleyiciler için kodlama yapmak için orada belirtilen tüm talimatları yürekten istemek gerçekten çok büyük bir şey. C'nin gömülü geliştirmede daha popüler olmasının nedeni budur, çünkü C, algoritmaları ve veri yapılarını donanıma bağlı ayrıntılardan soyutlayacak kadar yüksek seviyededir ve kaynak kodunu çok çeşitli hedef donanım, mimariden bağımsız dilde taşınabilir hale getirir ve kullanımı çok kolaydır. kodu dönüştürün ve koruyun. Ancak C, C ++, Python, Java vb. Gibi bazı üst düzey diller (nesne yönelimli) görüyoruz.


0

Sınırlamalar ve notlar ile C ++ 'ı öneririm.

  1. Pazarlama ve sürdürülebilirlik zamanı. C ++ geliştirme daha kolay ve daha hızlıdır. Bu nedenle, tasarım aşamasındaysanız, C ++ kullanmak için yeterince harika bir denetleyici seçin. (Bu seçimi yapamayacağınız bazı yüksek hacimli pazarların mümkün olduğunca düşük maliyet gerektirdiğini unutmayın.)

  2. Hız. C, C ++ 'dan daha hızlı olabilir, ancak bunun hız kazanımının büyük olmadığından emin olun. Böylece C ++ ile gidebilirsiniz. Algoritmalarınızı geliştirin, test edin ve gerektiğinde daha hızlı hale getirin (!). C hızına ulaşmak için darboğazları işaret etmek ve bunları harici "C" şeklinde yeniden yazmak için profil oluşturucuları kullanın . (Hala yavaşsa, bu bölümü ASM'de uygulayın)

  3. İkili boyut. C ++ kodları daha büyük, ancak burada ayrıntıları anlatan harika bir yanıt var. Belirli bir C kodunun derlenmiş ikilisinin boyutu, C veya C ++ derleyicisi kullanılarak derlenmiş olsa da aynı olacaktır. "Yürütülebilir dosya boyutu dil ile pek ilgili değil, projenize dahil ettiğiniz kitaplıklarla ilgilidir." C ++ ile gidin ama gelişmiş işlevleri önlemek gibi streams, string, new, virtualfonksiyonlar, vb İnceleme tüm kütüphane işlevi nedeniyle boyut sınırlaması, son kod onları izin vermeden önce (dayanan bu cevap)

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.