C ++ gömülü sistemler için uygun mu?


167

Burada ve başka yerlerde ortak bir soru. C ++ gömülü sistemler için uygun mu?

Mikrodenetleyiciler? RTOSes? Ekmek Kızartma? Gömülü PC'ler?

Mikroişlemcilerde OOP faydalı mı?

C ++ programlayıcıyı etkin olmak için donanımdan çok uzakta tutar mı?

Arduino'nun C ++ 'ı (dinamik bellek yönetimi olmadan, şablonlar, istisnalar hariç) "gerçek C ++" olarak mı düşünülmeli?

(Umarım, bu wiki bu potansiyel kutsal savaşı içerecek bir yer olarak hizmet edecektir)


5
Hızlı soru: gömülü derken , mikrodenetleyiciyi mi kastediyorsunuz? Mikroişlemci? gömülü x86 / gömülü PC?
J. Polfer

1
Kutsal bir savaşa neden olmaya niyet etmedim; amaç, argümanlarınızın buna karşı ne olduğunu öğrenmekti.
J. Polfer

2
Daha önce birkaç soru geldi, bu yüzden merkezi bir yerin iyi olacağını düşündüm.
Toby Jaffey,

4
C ++ vs gömülü çekişmeli bir konudur. Güçlü bir fikrim var ama bir soru sorup puanlamada oynamanın adil olduğunu düşünmedim. Umarım bir topluluk wiki daha dengeli bir tartışma için yapacaktır.
Toby Jaffey,

13
“Gömülü”, belirli bir dilin ve ilgili bagajın uygun olup olmadığına karar vermede anlamsız bir nitelik olduğundan, bu kötü bir sorudur. Önemli olan, küçük sistemlerin işletim sistemi çalıştırmadığı, hafızasının sınırlı olduğu, von-Neuman olmayabilir, arama yığınları, veri yığınları üzerinde çeşitli donanım kısıtlamaları olabilir, sadece Dinamik olarak bir Mb ayıramazsınız. hatta bir kb vb. Çoğu mikrodenetleyici "küçük" sistemlerdir. Tek kartlı bilgisayarlar genellikle gömülüdür, ancak genellikle "büyük" sistemlerdir.
Olin Lathrop

Yanıtlar:


135

Evet, C ++ gömülü sistemlerde hala faydalıdır. Diğer herkesin dediği gibi, hala sistemin kendisine bağlı, 8 bitlik bir UC'nin kitabımda bir hayır-hayır olacağı gibi, orada bir derleyici olsa ve bazı insanlar bunu yapıyorsa (titreme). 8 bitlik bir mikro dünyada bile, C ++ 'ı "C +" gibi bir şeye ölçeklendirirken bile C ++ kullanmanın bir avantajı var. "C ++" ile ne demek istiyorum? Yani, yeni / silme, istisnalardan kaçınma, kalıtımsal sanal sınıflardan kaçınma, muhtemelen birlikte mirastan kaçınma, şablonlara çok dikkat etme, makro yerine satır içi işlevleri kullanma ve constbunun yerine değişkenleri kullanma anlamına gelir #defines.

On yıldan uzun süredir gömülü sistemlerde hem C hem de C ++ 'da çalışıyorum ve C ++' a olan gençlik coşkuluğumdan bazıları, birisinin saflığını sallayan bazı gerçek dünya sorunları nedeniyle kesinlikle yıprandı. C ++ 'in en kötüsünü, "CS programcıları bir EE dünyasında çılgına döndü" olarak adlandırmak istediğim gömülü sistemlerde gördüm. Aslında, bu müşterileri ile birlikte üzerinde çalıştığım bir kod tabanı geliştirmek için üzerinde çalıştığım bir şey.

C ++ tehlikesi, dil ve genel programlamanın kendi içinde doğru şekilde eğitilmemesi ve disipline edilmemesi durumunda, hem kenarınızı hem de bacağınızı kesebilecek, iki ucu keskin bir kılıç gibi çok çok güçlü bir araçtır. C, tek kenarlı bir kılıç gibidir, ama yine de keskindir. C ++ ile çok yüksek seviyelerde soyutlama yapmak ve uzun vadede anlamsız hale gelen karışık arayüzler oluşturmak çok kolaydır ve bunun nedeni kısmen aynı sorunun birçok farklı dil özelliği ile çözülmesinde C ++ esnekliği olması (şablonlar, OOP, prosedür, RTTI, OOP + şablonları, aşırı yükleme, satır içi).

C ++ gurusu Scott Meyers tarafından C ++ 'in Embedded Software konulu 4 saatlik iki semineri bitirdim. Daha önce hiç düşünmediğim şablonlar hakkında ve güvenlik açısından kritik bir kod oluşturmaya ne kadar yardımcı olabileceklerini belirtti. Asıl mesele, katı güvenlik açısından kritik kod gereksinimlerini karşılamak zorunda olan yazılımda ölü kodunuz olamaz. Şablonlar bunu başarmanıza yardımcı olabilir, çünkü derleyici sadece şablonları başlatırken ihtiyaç duyduğu kodu oluşturur. Bununla birlikte, C'nin başarması daha zor olan bu özellik için doğru tasarım yapmak için kullanımlarında daha ayrıntılı bir şekilde eğitilmiş hale gelmek gerekir; çünkü bağlayıcılar her zaman ölü kodu optimize etmez.

Scott Meyers, şablonlar ve iç çizgilerin mantıklı kullanımı konusunda çok büyük bir destekçi ve yine de şablonlar konusunda çok becerikli olduğum konusunda şüpheci olduğumu söylemeliyim. Onlardan uzak durmaya meyilliyim, ancak en iyi araç oldukları yerde uygulanmaları gerektiğini söylüyor. Ayrıca C ++ 'ın size doğru kullanımı kolay ve yanlış kullanımı zorlaştıran arayüzleri gerçekten iyi yapmak için gerekli araçları sağladığını da belirtiyor. Yine, bu zor kısmı. En iyi tasarım çözümü olmak için bu özellikleri en etkili şekilde nasıl kullanabileceğinizi bilmeden önce, C ++ 'da ustalık seviyesine gelmelisiniz.

Aynı şey OOP için de geçerli. Gömülü dünyada, derleyicinin, çalışma zamanı polimorfizminin çalışma zamanı maliyetlerini idare edip edemeyeceğini bilmek için ne tür bir kodun tükeneceğini bilmek zorundasınız. Tasarımınızın son tarih gereksinimlerinizi karşıladığını kanıtlamak için ölçümler yapmaya istekli olmanız gerekir. Bu yeni InterruptManager sınıfı kesme gecikmemi çok uzun süre mi yapacak? C'nin de yapabileceği bağlantı zamanı polimorfizmi gibi probleminize daha iyi uyan başka polimorfizm türleri de vardır, ancak C ++ Pimpl tasarım deseni (Opak işaretçi) ile yapabilir .

Söylemek istediğim, C ++ 'nın gömülü dünyadaki yeri olduğunu söylüyorum. İstediğin kadar nefret edebilirsin, ama gitmiyor. Çok verimli bir şekilde yazılabilir, ancak bunu C ile doğru yapmayı öğrenmek daha zordur. Bazen bir problemi çözmede bazen C'den daha iyi çalışabilir ve bazen daha iyi bir arayüz ifade edebilir, ancak yine de kendinizi eğitin ve nasıl yapılacağını öğrenmekten korkmayın.


1
Bu, diğer gömülü sistem danışmanlarından okuduklarım ile aynı çizgide. Her zaman C ile sürekli kendini küçük yollarla kestiğini öğrendim, ama C ++ 'da bir böcek daha nadir olacak, ama batırdığın zaman bir bacağını kaybedeceksin. Sahip olmadığım uzmanlık ile net bir yanıt yazdığınız için teşekkür ederiz.
Kortuk

3
Bilgisayar Bilimleri notu üzerine, EE topraklarında çıldırıyor. İşimde sahip olduğumuz en kötü kod parçası bir CS uzmanı tarafından yazılmıştı. Sonsuza dek ona donanımın ne olduğunu öğretmeye çalıştık. UML kullanarak yapılandırılmış bir sistem yaptı ve uygun bir kalıtım kullanarak tüm sistemi java'da oluşturdu. Bir şey değişinceye kadar işe yaradı ve ardından özellikler eklemek ya da tamamen yeniden tasarlamak kötü bir yamalardı. Kod, her şeyi miras ile ne kadar iyice karıştırdığı için neredeyse kullanılamaz.
Kortuk

2
Sadece seni ısırtan hatalar değil, seni de ısırtacak kalıcı olmayan kodlar. Tabii ki, bu temiz C ++ özelliğini kullanarak bu projeyi başlattığınızda her şey yolunda gider, ancak 2 ya da 3 yıl sonra entropi, gelişirken ciddi bir çaba göstermediği takdirde devreye girer. Şu an karşı karşıya olduğum şey bu .. kod C ++ 'da zaman içinde daha hızlı çalışıyor.
Jay Atkinson

2
UML ve istatistik makineleri. Gerçekten de Miro Samek eşyalarına içine bakmak gerekir state-machine.com . Yeniden kırılması ve değiştirilmesi kolay olan verimli bir sistem kurdu, ancak bunu düzeltmek biraz zaman alıyor.
Jay Atkinson

2
Bu gerçekten sisteminize ve ne kadar kullanılabilir belleğinize bağlı. 8 bitlik bir mikroda çok az RAM içeren kod mu yazıyorsunuz? Öyleyse soyut arayüzlerde delirmekten kaçınmak daha iyi olabilir. Bellek bölümleriyle 32 bit gömülü sistemler gibi bir şey yazıyorsanız, bunun için gidin. Gerçekten tartmalısın. Örneğin, bu sınıfa dünyayı "sanal" olarak yerleştirdiğinizde, sisteme bağlı olarak, o nesneyi bildirdiğiniz her örnek için 8 bit, 16 bit veya 32 bit olabilen fazladan bir işaretçi elde edersiniz. Farkında olmayacaksın bile, ve adam,
Jay Atkinson

56

C ++ gömülü sistemler için kesinlikle uygundur. Şimdi, belirli bir mikroişlemciyi kullanıp kullanmama konusunda temel kriterim olarak iyi geliştirme araçlarının (veya bunların yokluğunun) varlığını / yokluğunu kullanıyorum.

Kaynak maliyetlerinin düşük olması nedeniyle gömülü sistemlerde kullanılması iyi olan C ++ alanları:

  • Sınıfların / yapıların iyi kullanımıyla getirilen modülerlik
  • Eğer derleyici onları verimli bir şekilde derlemek için iyi bir iş çıkarsa , şablonlar . Şablonlar, algoritmaların tekrar kullanılmasının farklı veri tiplerine getirilmesi için iyi bir araçtır.

Tamam alanlar:

  • sanal işlevler - Eskiden buna karşıydım, ancak kaynak maliyeti çok küçük ( nesne başına değil sınıf başına bir oylama ; nesne başına oy için bir işaretçi; sanal işlev çağrısı başına bir başvuru kaldırma işlemi) ve bunun büyük avantajı hangi tip olduklarını bilmek zorunda olmayan birkaç farklı tipte nesne içeren bir diziye sahip olmanıza izin vermesidir. Bunu son zamanlarda, her biri ayrı yöntemlerle bir I2C cihazını temsil eden bir dizi nesneye sahip olmak için kullandım.

Çoğunlukla küçük sistemlerde kabul edilemez olan çalışma zamanı ek yükünden dolayı kullanılmayan alanlar:

  • dinamik bellek ayırma - Başkalarının bu belirtmiştik ama başka önemli nedeni değil dinamik bellek ayırmayı kullanmak için bu zamanlama belirsizliği temsil etmesidir; gömülü sistemleri kullanmak için birçok neden gerçek zamanlı uygulamalar içindir.
  • RTTI (çalışma zamanı türü bilgisi) - bellek maliyeti oldukça büyük
  • istisnalar - kesin hızlanma, çarpma hızı nedeniyle

Giriş için teşekkürler. İlginç ve okuduklarımla çok benzer.
Kortuk

1
Aslında dinamik bellek ayırma işlemi iyidir ve bazen kaçınılmazdır. Bu dinamik bellek DEallocation (ve daha sonra yeniden kullanım) sorunudur. RTTI hafıza domuzudur, buna katılıyorum. Ancak istisnalar ile ilgili sorun nedir?
Wouter van Ooijen

1
@WoutervanOoijen: İstisnalarla ilgili sorun, / blok içinde fooçağrılar ve bir istisna atan bazı nesneler ve çağrılar oluşturursa , sistemin bir şekilde kontrole dönmeden önce yaratılan nesneler için yıkıcılar çağırmasıdır . İstisnalar tamamen devre dışı bırakılmadıkça, herhangi bir şey fırlatıp fırlatamayacağını bilmenin hiçbir yolu olmayacak ve bu nedenle bu olasılığa izin vermek için ekstra kod içermesi gerekir. Bununla ilgilenmek için "kontrol edilen istisnalar" ı içeren bir C ++ varyasyonu görmek istiyorum; istisnaların kaçmasına izin verebilecek rutinler ...bartrycatchbarbozbarfoobarboz
supercat 16

1
... böyle bildirilmesi gerekiyordu, o zaman sadece derleyicinin bu tür rutinlerin arayanlarına istisna işleme kodu eklemesi gerekliydi. Emin olmak gerekirse, gerekli tüm bildirimleri eklemek, gereksiz olanları da ümit etmekten kaçınmakla birlikte, biraz zahmetli olacaktır, ancak istisnai durumların, yararlı olmadıkları yerlere, ek yükü eklemeden kullanılmalarına izin verecektir.
supercat

3
@WoutervanOoijen: Bu arada, eğer ABI’yı ARM’de böyle bir istisna işleme göre tasarlarsam, istisna yoluyla çıkabilecek bir rutini çağıran kodun, R14’ün istenen adresten önce iki bayta işaret etmesi gerektiğini belirtirdim. Arayan, ÇAĞRI talimatını 16 bitlik bir kelime ile takip ettiğinde doğal olarak ortaya çıkar). Çağrılan rutin daha sonra add r15,r14,#2yerine normal olarak çıkar mov r15,r14; istisna yoluyla çıkmak için ldrhs r0,[r14] / add r15,r14,r0. Normal çıkış için sıfır çevrim maliyeti ve yığın çerçevesi kısıtlaması yok.
supercat,

36

Evet, C ++ gömülü sistemler için kesinlikle uygundur. Öncelikle C ve C ++ arasındaki fark hakkındaki birkaç yanılgıyı giderelim:

Gömülü bir mikroda, zaman ve alan kısıtlamaları konusunda endişeleriniz varsa, her zaman yüksek seviye dilleri dikkatli bir şekilde kullanmanız gerekecektir. Örneğin, bir çok MCU işaretçileri iyi işlemez ve bu nedenle yığını kullanırken çok verimsizdir. Bu, değişkenleri işlevlere geçirme, dizileri ve işaretçileri kullanma ve özyineleme konusunda dikkatli olmanız gerektiği anlamına gelir. C gibi basit bir çizgi:

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

Bu değişkenlerin niteliğine bağlı olarak yaklaşık 4 sayfa talimat üretebilir.

Herhangi bir yüksek seviyeli dil kullanıyorsanız ve zaman ve mekan kısıtlamaları konusunda endişe duyuyorsanız , o dilin her özelliğinin MCU'nuzdaki makine talimatlarına nasıl dönüştüğünü bilmeniz gerekir (en azından kullandığınız her özellik). Bu, C, C ++, Ada için geçerlidir. Muhtemelen tüm diller, küçük MCU'larda verimli bir şekilde çeviri yapmayan özellikler içerecektir. Derleyicinin önemsiz bir şey için talimatlar toplamadığından emin olmak için her zaman sökme listelerini kontrol edin.

C gömülü MCU'lar için uygun mu? Evet, oluşturulan koda göz kulak olduğunuz sürece.
C ++ gömülü MCU'lar için uygun mu? Evet, oluşturulan koda göz kulak olduğunuz sürece.

İşte bu yüzden C ++ 'ın 8-bit MCU'larda bile C'den daha iyi olduğunu düşünüyorum: C ++ aşağıdakiler için gelişmiş destek sağlar:

  • Veri gizleme
  • Daha güçlü yazma / kontrol
  • Sınıfları kullanarak çok periferik şeffaflık
  • Şablonlar (dikkatli kullanılırsa her zamanki gibi)
  • Başlatma listeleri
  • const

Bu özelliklerin hiçbiri C'nin tipik özelliklerinden daha ağır değildir.

16 veya 32 bit MCU'ya kadar ilerlerken, C'nin (yığın, yığın, işaretçiler, diziler, printf, vb.) Daha ağır özelliklerini kullanmanın bir anlamı olmaya başlar. Aynı şekilde, daha güçlü bir MCU uygun olur. C ++ 'ın daha ağır özelliklerini kullanmak için (yığın, yığın, referanslar, STL, yeni / sil).

Yani, bir PIC16 üzerindeki C ++ düşüncesinde titremeye gerek yok. Dilinizi ve MCU'nuzu doğru bir şekilde biliyorsanız, o zaman ikisini birlikte nasıl etkili kullanacağınızı bileceksiniz.


3
Bu, sorunun çok iyi ifade edilmiş ve makul bir cevabıdır. +1 Şerefe!
vicatcu

1
" a[i] = b[j] * c[k];Bu değişkenlerin niteliğine bağlı olarak yaklaşık 4 sayfa talimat üretebilir." MCU'nuz / derleyiciniz bunu yaparsa, bunun nedeni 80'lerden kalma bir garaj hobisi işlemcisi kullanıyor olmanızdır.
Lundin

@ Lundin - Sigh. Hayır, yığın indeksleme gibi karmaşık şeylere sahip olmamak için mümkün olduğu kadar küçük ve ucuz olacak şekilde tasarlanmış ucuz bir MCU kullandığınız anlamına gelir.
Rocketmagnet

2
@Rocketmagnet Tamam belki 1990'larda? Bugünlerde berbat 8 ​​acı, 32 acı ile aynı fiyata geliyor. Birincisini seçmek için geriye kalan tek şey mevcut tüketimdir. Ve yığınsız 8-bit-bitters ile ilgili: böyle sınırlı bir MCU için assembler yerine C yazıyorsanız, muhtemelen yanlış yapıyorsunuz. Oluşturulan 4 sayfa daha sonra CPU için çok karmaşık programlar yazmak sizin kendi suçunuzdur ve aslında C, görev için yanlış bir araçtır. (Bunu daha önce Freescale RS08'de yaptım, çok aptalca bir fikirdi.)
Lundin

@ Lundin 32-bit işlemci 16-bit'den daha hızlı bir işlem gerektirmez. Bu, PC dünyasında 16 - 32 bitlik bir program geçişinin gerçekleştiği günlerde ortaya çıkmıştı.
Barleyman

24

Bu tartışmaları her zaman okumayı eğlenceli buluyorum. Mevcut çeşitli dillerin artıları ve eksileri hakkındaki entelektüel tartışmalar için çok değil, ancak iş / deneyim / ilgi alanlarına göre genellikle bir kişinin konuyla ilgili duruşunu sabitleyebildiğiniz için. Sağda "erken optimizasyon" argümanları var, CS ana dalları ve bakım programcıları Knuth'un soldan ve sağdan alıntı yaptıkları ve performans meselelerinin hepsinin çılgınca olduğunu düşündüğü gerçek dünyada çalışanlar olduğunu söylediler. adil olmak).

Günün sonunda, C veya C ++ ile mükemmel yazılımlar geliştirebilir veya buraya dil ekleyebilirsiniz . Dil değil, geliştiricinin yetenekleri ile ilgilidir. Bir dilde uzman olmak genellikle sadece başlangıç ​​için yanlış dili seçtiyseniz ve şimdi probleminizi çözme konusunda uyarmanız gerekirse, çoğu durumda bunlar karanlık özelliklere veya derleyiciye dalmanız gereken tek durumdur. Hedefi gerçekleştirmek için püf noktaları.

Sık sık insanların bu argümanları "X dili ve filan filan konusunda uzmanım" diye başlattığını duyuyorum. Bu insanları dürüstçe derhal reddediyorum, çünkü bence soruna zaten yanlış açıdan yaklaşmışlar ve ondan sonraki her şey. Sorunu çözmek için araçlarını kullanma arzusuyla ve ne kadar 'soğuk' olduğunu gösterme arzusuyla.

Sık sık geliştiricilerin önce bir araç seti seçtiklerini ve problemlerini ikinci kez bükmeye çalıştıklarını izliyorum, bu tamamen yanlıştır ve saçma çözümlere yol açar.

Başka bir cevaba yapılan bir yorumda bahsettiğim gibi, bu dil savaşları, X dilinin programcının daha aptalca şeyler yapmasına izin verdiğini savunarak sık sık gelişir. Okumak için eğlenceli olsa da, tüm bu ifadeler gerçekten iyi geliştiricileri işe alma konusunda bir sorun yaşamanız ve kötü geliştiricileri işe almaya devam ederek ve bu kadar az şey yapabilecekleri araçlar seçerek duruma yardım etmeye çalışmak yerine doğrudan bu konuyu ele almanız gerektiği anlamına geliyor. mümkün olduğu kadar zarar.

Bence iyi geliştiriciler, yazılım veya donanım geliştirme, sorunu araştırmak, bir çözüm inşa etmek ve çözümü 'en iyi şekilde' ifade etmelerine olanak sağlayan araçları bulmak. Gereken aracın daha önce hiç kullanmadığınız bir şey olup olmaması önemli değil, yeni bir tane toplayan projeler için 3-4 dil / geliştirme aracı kullandıktan sonra geliştirme sürenizi en az etkileyecektir.

Tabii ki, 'en iyi yol' öznel bir terimdir ve ayrıca araştırma aşamasında tanımlanması gerekir. Kişinin çok sayıda konuyu göz önünde bulundurması gerekiyor: performans, ifade kolaylığı, kod yoğunluğu, vb. Eldeki soruna göre. Bir sebeple o listeye sürdürülebilirliği dahil etmedim, uygun aracı seçtiyseniz ve bu sorunun 'bedavaya gelmesi' problemini anlamak için zaman ayırırsanız, hangi dili seçtiğiniz umrumda değil. Kodu korumak zor, genellikle yanlış aracı veya zayıf bir sistem yapısını seçmenin sonucudur, bu da çalışmasını sağlamak için çirkin bir karmaşaya yol açar.

Herhangi bir dilin iddia edilmesi, diğerlerinden daha 'iyidir', belli bir ilgi problemini tanımlamaksızın aptalcadır. Nesneye yönelik bir yaklaşım, işlevsel bir yaklaşımdan her zaman daha iyi değildir. Nesne yönelimli tasarım paradigmasına kendilerini iyi borç veren bazı problemler var. Yapmayanlar var. Aynı ifade, insanların uğraşmaktan hoşlandıkları birçok dil özelliği hakkında da yapılabilir.

Zamanınızın% 20'sinden fazlasını kod yazarken bir soruna harcıyorsanız, muhtemelen çok zayıf bir sistem üretiyorsunuz veya çok zayıf geliştiricilere sahip oluyorsunuz (ya da hala öğreniyorsunuz). Zamanınızın büyük bölümünü sorunu çizerek ve uygulamanın çeşitli parçalarının nasıl etkileşime girdiğini belirleyerek geçirmelisiniz. Bir grup yetenekli geliştiriciden bir gruba bir işaret panosuyla yapıştırma ve bunları çözme ve söyleme sorunu, tüm sistemde kendilerini rahat hissedinceye kadar herhangi bir kod yazmalarına veya herhangi bir araç seçmelerine izin verilmemesi gerektiğini söyleme problemi. Geliştirme süresini iyileştirmek için garantili olan herhangi bir yeni aracı seçmek yerine çıktı ve hız gelişimi. (tartışmamın karşısındaki kutup için referans olarak scrum gelişimini araştırın)

Genellikle talihsiz gerçeklik, birçok işletmenin bir geliştiricinin değerini yalnızca yazılmış satır sayısıyla veya 'somut çıktıyı' görerek ölçebilmesidir. 3 haftada bir marker kartı bulunan bir odada üretkenlik kaybı olarak görüyorlar. Geliştiriciler genellikle 'düşünce' geliştirme aşamasını hızlandırmak zorunda kalırlar ya da "Patronumun kardeşi IBM için çalışıyor, bu yüzden bu aleti kullanabilmemiz için," araçlarını kullanabilmemiz için "şirket içinde bazı politik meseleler tarafından belirlenen bir aracı kullanmak zorunda kalıyorlar. . Daha da kötüsü, şirketten sürekli olarak değişen gereksinimler elde edersiniz, çünkü doğru pazar araştırması yapamazlar veya değişikliklerin gelişim döngüsü üzerindeki etkilerini anlamadılar.

Bu rant ile konu dışı olduğum için üzgünüm, bu konuda oldukça güçlü görüşlerim var.


2
Şimdi, belirli gömülü sistemlerde uygulama düzeyinde (sürücünün üstünde) birim testleri gerçekleştirmiyorum. Birim test etme ve geliştirme aşamasının erken dönemindeki hataları gidermenin anlık geri bildiriminin bir değeri vardır, ancak TDD'nin tasarıma doğurmak için verdiği paradigma bana biraz zor geliyor. Sorun hakkında "düşünmek" için biraz zaman ayırmayı ve kodlamaya başlamadan önce ya kafamda, kağıda ya da beyaz tahtada çizmeyi tercih ederim. TDD'nin piyasayı gereklilikler üzerine ön araştırma yapmayacağına cesaretlendirdiğini düşünüyorum, çünkü sürekli ihtiyaç değişiminde yardımcı olması gerekiyor.
Jay Atkinson

2
Ve benim süper uzun yorumumun üzerine bir son not koymak için .. Tasarım çalışması için dil uzmanlarına ihtiyacımız yok. Dilleri çalıştırabilen uzman tasarımcılara ihtiyacımız var.
Jay Atkinson

1
PRD = ürün gereksinimleri belgesi, MRD = pazarlama gereksinimleri belgesi, TRD = teknik gereksinimler belgesi. TDD = Test Odaklı Geliştirme.
Jay Atkinson

1
@Mark - Ön hazırlık düşüncelerinize katılıyorum, ancak yalnızca bir noktaya. Ağır ön hazırlık çalışmalarının, a) gereksinimleriniz oldukça kararlı / biliniyorsa ve b) tasarımı yapan geliştiricilerin deneyimlemesi durumunda işe yarayacağını düşünüyorum . Bir önceki iş, bir tasarım yapmakla görevliydi ve ekibimin liderliği tarafından büyük ölçüde zaman damgalıydı ve "Ne kadar aptalca bir şey! Tasarım hazırlığı para tasarrufu sağlar (cf. Kod Komple kitabı) ??" diye düşündüm. Ancak kodlamada aramayı bilmediğim tonlarca şey keşfettim. Çok fazla tasarım yapıp kod zamanını en aza indirmiş olsaydım, bir israf olurdu. JME.
J. Polfer

1
@sheepsimulator Açıkçası ikinci noktada katılıyorum, öncü sistemin mimarlarının deneyimli geliştiriciler olduğunu varsayıyorum. İlk noktada ben aslında katılmıyorum. İhtiyaçlarınızın tasarım aşamasında harcayacağınız zamanı daha fazla değiştirmesini beklediğinizi düşünüyorum çünkü iyi, değişmesi kolay, iyi bir tasarım üretmeniz gerekiyor. Bazı felsefelerin hızlı gelişme önerdiğini biliyorum. Bazı durumlarda bu, personel konusunda çok sayıda kötü ya da deneyimsiz programcı gibi çalışır. Tüm bu tasarım felsefeleri, "esnek bir sistem tasarlamak için dua edemiyorum, bu yüzden denemeye zaman harcamamıza izin veriyor" diyor.
Mark

17

Herhangi bir dil gömülü bir sistem için uygun olabilir. Gömülü sadece anlamına gelir: ücretsiz kullanımlı bir bilgisayar yerine, daha büyük bir cihazın parçası.

Sorunun ( zor ) gerçek zamanlı ya da sınırlı kaynaklar için bir sistem istendiğinde daha fazla alakası vardır .

Gerçek zamanlı bir sistem için C ++, sıkı zaman kısıtlamaları için programlama yaparken hala uygun olan en yüksek dillerden biridir. Yığın kullanımı (serbest operatör) dışında, belirsiz bir yürütme süresine sahip hiçbir yapıları yoktur, bu nedenle programınızın zamanlama gereksinimlerini karşılayıp karşılamadığını test edebilirsiniz ve biraz daha tecrübe ile onu bile tahmin edebilirsiniz. Yığın kullanımından kaçınılmalıdır, bununla birlikte, yeni operatör hala bir kerelik tahsis için kullanılabilir. C ++ 'nın C üzerinden sunduğu yapılar gömülü bir sistemde iyi kullanılabilir: OO, istisnalar, şablonlar.

Kaynak sınırlı sistemler için (8 bit yongalar, birkaç Kb RAM'den az, erişilemez yığın yok) tam C ++ uygun olmayabilir, ancak yine de 'daha iyi C' olarak kullanılabilir.

Ada'nın sadece bazı nişlerde kullanıldığını görünmesinin talihsiz olduğunu düşünüyorum. Bir çok yönden bir Pascal ++, ama başlangıçta zaten ciddi bir karışıklık olan bir dille yukarı doğru uyumlu olma yükü olmadan. (düzenleme: ciddi karışıklık elbette C. Pascal, güzel ama biraz pratik bir dildir.)

================================================== ==============

EDIT: Yeni soruya cevap yazıyordum ("Mikrodenetleyicileri programlarken hangi durumlarda C ++ gerekli?"), Buna atıfta bulunuldu, bu yüzden yazdıklarını ekleyeceğim:

Herhangi bir programlama dilinin kullanımı için hiçbir zaman geçersiz kılma nedeni yoktur , ancak belirli bir durumda daha fazla veya daha az ağırlığa sahip argümanlar olabilir. Bununla ilgili tartışmalar, birçok yerde bulunabilir; pozisyonları "mikro denetleyici için asla C ++ kullanmayın" dan "daima" C ++ kullanmayın "a kadar olan konumlar. Ben son pozisyonda daha varım. Bazı argümanlar verebilirim, ancak belirli bir durumda (ve hangi yönde) ne kadar ağırlık taşıdıklarına kendiniz karar vermelisiniz.

  • C ++ derleyicileri C derleyicilerinden daha nadirdir; Bazı hedefler için (örneğin, 12 ve 14 bit çekirdekli PIC'ler), hiçbir C ++ derleyicisi yoktur.
  • (iyi) C ++ programcıları (iyi) C programcılarından daha nadir, özellikle elektronikte de (biraz) bilgili olanlar arasında.
  • C ++, küçük sistemler için uygun olmayan (istisnalar, RTTI, yığının sık kullanımı gibi) C'den daha fazla yapıya sahiptir.
  • C ++, C'den daha zengin (standart) kitaplık kümesine sahiptir, ancak önceki noktanın bir sonucu olarak, C ++ kitaplıklarının genellikle küçük sistemler için uygun olmayan ve bu nedenle küçük sistemlerde kullanılamayan özellikleri kullanması gerekir.
  • C ++ 'ın kendini ayağından vurman için izin veren C'den daha fazla yapısı var.
  • C ++, kendinizi ayağınızdan vurmanızı engellemenizi sağlayan C'den daha fazla konstrüksiyona sahiptir (evet, IMO bu ve önceki ikisi de geçerlidir).
  • C ++ daha zengin bir soyutlama mekanizmasına sahiptir, bu nedenle özellikle kütüphaneler için daha iyi programlama yolları sağlar.
  • C ++ dil özellikleri (örneğin, inşaatçılar / yıkıcılar, dönüşüm fonksiyonları), üretilen makineyi görmek için kodda görmeyi zorlaştırır ve böylece bir dilin yapısının uzay ve zamanındaki maliyeti.
  • C ++ dil yapısının, makine koduna tam olarak ne şekilde çevrildiğinin farkında olmamak daha az gerekli çünkü daha doğru bir şekilde 'doğru şeyi' yapıyorlar.
  • C ++ dil standardı hızlı bir şekilde gelişmektedir ve büyük derleyiciler (gcc, clang, microsoft) tarafından hızla benimsenmiştir. C oldukça sağlam bir şekilde evrimleşiyor ve bazı yeni özelliklerin (değişken diziler) benimsenmesi korkutucu ve hatta daha sonraki bir standartta geri döndürülmüş durumda. Özellikle bu nokta, farklı insanların zıt pozisyonları desteklemek için kullanması nedeniyle ilginçtir.
  • C ++ hiç şüphesiz C'den daha keskin bir araçtır. Programlayıcılarınıza (veya kendinize) güzel bir heykel yapmak için böyle bir araç kullanma konusunda güveniyor musunuz, yoksa kendilerini incitmelerinden korkuyor musunuz ve daha az güzel fakat daha az riskli bir ürüne razı olmayı mı tercih ediyorsunuz? ? (Heykel öğretmenimin bir keresinde künt araçların bazı durumlarda keskin olanlardan daha tehlikeli olabileceğini söylediğini hatırlıyorum .)

Benim blog küçük sistemlerde (= mikro denetleyicileri) C ++ bazı yazıları vardır.


15

Benim tecrübeme göre, C ++ genellikle küçük gömülü sistemler için uygun değildir. Demek istediğim, mikrodenetleyiciler ve işletim sistemi gerektirmeyen cihazlar.

Birçok C ++ OOP tekniği dinamik bellek tahsisine dayanmaktadır. Bu genellikle küçük sistemlerde eksiktir.

STL ve Boost, her ikisinin de ayak izi konusunda çok büyük olan C ++ 'nın gücünü gösteriyor.

C ++, programcıyı kısıtlı sistemlerde kucaklanması gereken makineyi soyutlama konusunda teşvik eder.

Geçen sene ticari bir uzak masaüstü ürününü cep telefonlarına taşıdım. C ++ dilinde yazılmıştır ve Windows, Linux ve OSX ile çalışmaktadır. Ancak, yoğun olarak STL, dinamik bellek ve C ++ istisnalarına dayanıyordu. WinCE, Symbian ve OS'siz ortamlarda çalışmaya devam etmek için en yeni seçenek C yazısını yeniden yazmaktı.


Küçük sistemlere referans olarak katılıyorum, ancak küçük sistemlerin farklı tanımlarına sahip olduğumuzu düşünüyorum. Eğer 1kB ROM’a sahipseniz ve iyi yazılmış C kodu ROM’un 1 baytı dışında hepsini alır, bu küçük bir sistemdir.
Kortuk

6
C'nin daha küçük bir ayakizine sahip olamayacağını iddia etmiyorum, ama hala C ++ 'yı kullanıp, tartışılanın tasarımı için çok benzer bir sonuç elde etmiş olabilirsiniz. Bence sorun, çoğu OOP programlayıcısının dinamik hafızalı ve çok yetersiz yapılı yapılar kullanan sistemlerde kullanıldığını ve düşük güç sistemleri için tamamen işe yaramaz bir kod üretildiğini düşünüyorum.
Kortuk

4
peki demek istediğiniz şey C ++ kullanmak istemiyorsanız, C ile C ++ arasında bir şey kullanmak istiyorsunuz (sadece C + diyelim). Bu durumda, katılıyorum, C ++ insanlarında bir sürü saçmalık var, sadece uygun olduğu için kullanıyor, optimal olduğu için değil. Hemen hemen her dil iyi, hızlı kod üretme yeteneğine sahiptir, onun kullanımı nasıldır. Dillere yapılan en kutsal savaşlar, dil yeteneklerinin bir sonucu değil, bir aptalın aptalca şeyler yapmasının ne kadar kolay olduğu konusundaki bir argümandır, bu gerçekten aptalca bir argümandır: p
Mark

2
“Dillere karşı yapılan en kutsal savaşlar, dil yeteneklerinin bir sonucu değil, bir aptalın gerçekte aptalca bir argüman olan aptalca şeyler yapmasının ne kadar kolay olduğu konusundaki bir tartışma.” Çok keyifli bir cümle oldu. Soyadıma ihtiyacım var, böylece bir alıntı yapabilirim.
Kortuk

1
Gerçekten de dinamik belleği C de kullanmıyorum. Sahip olmam gereken hiçbir yer yok. Uzun vadede çok parçalanabileceğini ve sorun çıkarmaya başladığını okudum. Hafızamız tükenmek için çok net bir şekilde tasarlanmış kasalara ihtiyacım var ve ne kadar kaldığını tam olarak izleyebilmeliyim.
Kortuk

11

Çıplak metal ve kaynak kısıtlı sistemlerdeki C ++ hakkındaki bu tartışmaya ısıdan daha fazla ışık katmayı umuyorum.

C ++ ile ilgili sorunlar:

  • İstisnalar özellikle gerekli “acil durum tamponu” (örneğin, hafıza dışı istisnaların geçerli olduğu) mevcut RAM'den daha büyük olabileceği ve kesinlikle mikrodenetleyiciler için boşa harcanan bir RAM problemidir. Daha fazla bilgi için bkz. N4049 ve n4234 . Kapatılmaları gerekir (şu anda belirtilmemiş olan davranışlardır, bu nedenle emin olun ve asla atmayın). SG14 şu anda bunu yapmanın daha iyi yolları üzerinde çalışıyor.

  • RTTI muhtemelen hiçbir zaman ek yüke değmez, kapatılmalıdır

  • Büyük hata ayıklama, hata ayıklama yongasına sığmazsa, bu klasik masaüstü geliştirme bir sorun olmasa da, bir sorun olabilir. Sorun, şablonlu koddan veya netlik için eklenen ekstra işlev çağrılarından kaynaklanmaktadır. Bu ekstra fonksiyon çağrıları, optimizer tarafından tekrar kaldırılır ve eklenen netlik veya esneklik büyük bir avantaj olabilir, ancak hata ayıklama yapılarında bu bir problem olabilir.

  • Yığın tahsisi. STL özel ayırıcıların kullanımına izin vermesine rağmen, çoğu programcı için bu karmaşık olabilir. Yığın tahsisi deterministik değildir (yani zor gerçek zamanlı değildir) ve parçalanma, testlerde çalışmış olmasına rağmen beklenmedik bellek durumlarının ortaya çıkmasına neden olabilir. Boş alanın ve değişen boyutun izini sürmek için yığın tarafından ihtiyaç duyulan kitap küçük nesnelerde sorun olabilir. Havuz tahsisini kullanmak genellikle daha iyidir (hem C hem de C ++ 'da) ancak bu yalnızca öbek kullanarak kullanılan C ++ programcıları için anormal olabilir.

  • Çalışma zamanı polimorfizmi ve diğer dolaylı çağrılar genellikle büyük bir performansa neden olur, sorun genellikle daha fazladır, çünkü optimizer, onlardan daha çok göremez ve adrese atlamaktan daha fazlasını göremez. Bu nedenle, C ve C ++ 'da C ++' da olduğu gibi kültürde daha köklü (ve diğer alanlarda oldukça faydalıdır) dolaylı çağrılardan kaçınılmalıdır.

  • clib ile örtülü arayüzleme problemli olabilir. Uçbirim sorunlarının C ++ kategorisinde yer alması, ancak sorunun kaynağın eşzamanlı ortamlarda paylaşılmasından kaynaklanıyor olabilir (paylaşım, C'de daha belirgindir). Yaygın newLib uygulamasının kullanımı çoğu zaman uC'lerde gerekmeyen çok fazla şişkinliğe sürüklenir, diğer yandan da newLibNanno yeniden gönderilmez, bu nedenle erişimin seri hale getirilmesi gerekir (burada basitleştirilir). Bu, C için de bir problemdir ancak erişim daha açıktır. Temel kural olarak, bir şekilde uçurumdaki duruma erişmediğinden emin olmadıkça ISR bağlamında std ad alanından hiçbir şey kullanmamalısınız (örneğin, hata veya öbek). Ayrıca malloc ve free erişimi senkronize etmek için yeniyi silmek ve silmek için iş parçacığı kullanıyorsanız (RTC'yi tercih ederim) de önemlidir.

Sonuç olarak, C ++ 'in bazı problemleri vardır, ancak hepsi düzeltilebilir veya önlenebilir niteliktedir.

Şimdi C için, burada sorun daha yüksek sırada. C'deki şeyleri, optimizasyon uygulayabileceğim veya soyutlayıcıları derleme zamanında kontrol edebileceğim bir şekilde soyutlayabilecek sözdizimsel yeteneğim yok. Bu nedenle, bir şeyi kullanıcının bunları kullanmak için nasıl çalıştığını bilmesi gerekmeyecek şekilde düzgün bir şekilde kaplayamıyorum ve hata saptamamın çoğu çalışma zamanında (yalnızca çok geç değil, aynı zamanda maliyet de ekliyor) yapılır. Temel olarak C de jenerik olmanın tek yolu verilerden geçiyor, örneğin çalışma zamanında değerlendirilen printf veya scanf için bir format dizgisi yapıyorum. Derleyicinin doğru veriyi ilettiğinde teorik olarak mümkün olan seçeneklerin bazılarını kullanmadığımı kanıtlaması oldukça zor. Bu, potansiyel ölü kod üretimi ve optimizasyon potansiyelinin kaybı anlamına geliyor.

Burada bir fırtınayı açığa çıkarabileceğimi biliyorum ama 32 bit mikrodenetleyicilerdeki deneyimim, bir elmada elma ve elma ile C ve C ++ karşılaştırmasının her ikisi de uzmanlar tarafından yazılan (C ++ 'da potansiyel olarak yüksek tempolu) olduğu gibi. herhangi bir şey (herhangi bir kütüphanede olduğu gibi) jenerik olmalı ve jenerik olmayan durumlarda esasen eşdeğerdir. Ayrıca bir aceminin C ++ 'daki uzman bir kütüphane uygulayıcısının uzmanlığından yararlanması daha kolaydır.

Aynı zamanda, yanlış veri iletemediğim, gerçekten bir kaç fonksiyon var, girdi bir int değil, bir int somethingkullandığım için int kullandığım bir int yöntemi olarak kullandığım bir fonksiyon var. yanlış ('bir şey' yerine geçersiz bir değer veya 'otherThing' iletin). C'de kullanıcının yanlış olup olmadığını kontrol etmemdeki tek yöntem çalışma zamanında. C ++ 'da bazı kontrolleri yapma yeteneğine sahibim, tüm kontrolleri değil, bazı ücretsiz kontrolleri derleme zamanında yapıyorum.

Günün sonunda, bir C takımı genellikle en zayıf programcısı kadar güçlüdür ve ortaya çıkan kodun yararı, ya çok oyunculu 1'e ya da performans cezasına sahiptir. Bununla kastettiğim, benzersiz tasarım kararlarının benzersiz bir ortamında tek ve tek bir iş için yüksek performans veya birden fazla ortamda (diğer mikrodenetleyici, diğer bellek yönetimi stratejisi, diğer gecikme vs. işlem hacmi vb.) ama doğası gereği performans maliyetine sahiptir.

C ++ 'da işler uzmanlar tarafından kapsüllenebilir ve derleme zaman kodu oluşturmanın belirli bir işe adapte olduğu birçok ortamda kullanılabilir ve statik kontrol, kullanıcıların aptal işleri sıfır maliyetle yapmalarını önler. Burada genel olma ve hızlı olma arasında çok daha az şey var ve sonuçta maliyet ve fayda açısından daha etkili, daha güvenli ve daha verimli bir dil var.

Gömülü için hala iyi bir C ++ kütüphanesi sıkıntısı olduğuna dair geçerli bir eleştiri, bu, C ++ derleyicisinde çoğunlukla C kullanımı için pragmatik kararlara yol açabilir. Bir projede yalnızca C kullanma kararları esasen ya ideolojik olarak yönlendirilir, eski desteğe ihtiyaç duymaz ya da ekibin C ++ 'ta yapabileceği, C' de yapamayacağı çok aptalca şeylerden sakınacak kadar disiplinli olmadığını kabul eder. ve aynı zamanda, C'ye karşı koyamayacağı ancak C ++ 'ta yapamayacağı kadar büyük aptalca şeylerden hiçbirini yapamayacak kadar disipline edilmiştir.


Cevabımı güzel ek :) Bu gizemli C ++ sevgilisi kim olabilir? Profili, "Görünüşe göre, bu kullanıcılar, onlar hakkında gizemli bir hava tutmayı tercih ediyor" diyor. (kötü ingilizce, btw) ama aha konum "bochum, almanya" ..... konferansta görüşmek üzere!
Wouter van Ooijen,

Ah evet profilimi güncelledi;) emBO ++ 'a geldiğini bilmek güzel
odinthenerd

10

Geçmişim: eski Bell Labs programcıları altındaki okul eğitimi dışında; 3 senedir 2'si araştırma projesi üzerinde çalışıyor; VB.NET'te veri toplama / işlem kontrolü. 1.5 yıl VB6'da bir kurumsal veritabanı uygulaması üzerinde çalışarak geçirdim. Halen 2GB depolama alanı, 512 MB RAM, 500MHz x86 CPU içeren gömülü PC için proje üzerinde çalışıyor ; C ++ ile aynı anda çalışan birkaç uygulama arasında bir IPC mekanizması var. Evet gencim.

Benim fikrim: C ++ yukarıda yazdığım ortam göz önüne alındığında etkili çalışabileceğini düşünüyorum . Kuşkusuz zor gerçek zamanlı performans, bulunduğum uygulama için ve bazı gömülü uygulamalarda bu bir sorun olabilir. Ama işte öğrendiğim şeyler:

  • C ++, temel olarak C'den farklıdır (yani, C / C ++ yoktur). C'nin geçerli olduğu her şey geçerli C ++ olsa da, C ++ çok farklı bir dildir ve birinin C'yi değil, herhangi bir durumda etkili bir şekilde kullanabilmesini C ++ ile nasıl programlayacağınızı öğrenmeniz gerekir . C ++ 'da nesne yönelimli, yordamsal değil ve ikisinin bir melezi değil (çok işlevli büyük sınıflar) programlamanız gerekir. Genel olarak, az işlevli küçük sınıflar oluşturmaya odaklanmalı ve tüm küçük sınıfları daha büyük bir çözümde oluşturmalısınız. İş arkadaşlarımdan biri bana büyük bir karmaşa olan ve bakımı zor olan nesnelerde prosedürel olarak programladığımı açıkladı. Daha fazla nesne yönelimli teknik kullanmaya başladığımda kodumun korunabilirliği / okunabilirliğinin arttığını gördüm.

  • C ++, okumayı / bakımını kolaylaştırmak için kodu basitleştirmenin bir yolunu sağlayabilen nesne yönelimli geliştirme şeklinde ek özellikler sunar . Dürüst olmak gerekirse, OOP'yi yaparken performans / alan verimliliğini artırmanın pek bir yolu olduğunu sanmıyorum. Ancak, OOP'nin karmaşık bir problemi birçok küçük parçaya bölmesine yardımcı olabilecek bir teknik olduğunu düşünüyorum. Ve bu kod üzerinde çalışan insanlar için yararlıdır, bu sürecin göz ardı edilmemesi gereken bir unsurdur.

  • C ++ 'a karşı birçok argüman öncelikle dinamik bellek tahsisi ile ilgilidir. C de aynı sorunu var. Dinamik bellek kullanmadan nesne yönelimli bir uygulama yazabilirsiniz, ancak nesnelerin kullanılmasının yararlarından biri bu şeyleri dinamik olarak kolay bir şekilde tahsis edebilmenizdir. Tıpkı C'de olduğu gibi, bellek sızıntılarını azaltmak için verilerin nasıl yönetileceğine dikkat etmeniz gerekir, ancak RAII tekniği C ++ 'da bunu daha basit hale getirir (dinamik belleği otomatik olarak nesnelere kapatarak). Her bellek konumunun önemli olduğu bazı uygulamalarda, bu yönetilemeyecek kadar vahşi ve yünlü olabilir.

DÜZENLE:

  • "Arduino C ++" sorusunu WRT : Dinamik bellek yönetimi olmadan C ++ 'nın hala faydalı olabileceğini iddia ediyorum . Kodunuzu nesnelere düzenleyebilir ve ardından bu nesneleri uygulamanızın içindeki çeşitli konumlara yerleştirebilir, geri arama arabirimleri oluşturabilir, vb. Artık C ++ ile geliştirdiğim için, uygulamanın tüm verileri içeren bir uygulamanın, stack hala nesnelerle faydalı olabilir. Yine de itiraf edeceğim - aslında Arduino için böyle bir gömülü uygulama yazmadım, bu yüzden iddiamın arkasında hiçbir kanıt yok. Gelecekteki bir projede Arduino gelişimi için bazı fırsatlarım var - umarım iddialarımı orada test edebilirim.

2
İkinci noktanız üzerine yorum yapmak isterim, bunun karmaşık bir problemin küçük parçalara ayrılmasına yardımcı olduğunu ve bu özelliğin göz ardı edilmesi gerektiğini söylüyorsunuz. Bu yüzden pro-C ++ olduğumun kesin sebebi bu. Programlamaya yönelik çok geniş bir araştırma kapsamı, program büyüklüğündeki doğrusal bir büyümenin gelişim süresinde üssel bir büyüme sağladığını göstermektedir. Bunun tersi bir yol izler, eğer bir programı uygun şekilde bölebilirseniz, geliştirme süresinde üssel bir bozulma verebilirsiniz. Bu çok önemli bir şey.
Kortuk

İkinci noktasında da: Basitçe bir OOP tasarım metodolojisi kullanmak daha fazla bölümlenmiş kod üretmiyor. İyi bir temel tasarıma sahip olmak, o tasarımın nasıl ifade ettiği geliştiriciye bırakılır. OOP, kodunuzu doğru bir şekilde ayırmanızı tanımlamıyor, başka bir seçenek ve daha fazlası için yaptığınız görünümü sağlıyor, ancak geliştiriciye kalmış iyi bir tasarım uygulamıyor.
Mark

Bu her zaman doğrudur. İyi tasarım uygulayan bir dil hiç duymadım. Sanırım çoğunlukla bunun geliştiricilerin işi olduğunu ve C ++ 'nın organize bir şekilde kullanılmasını ve uygulanmasını kolaylaştırdığını ima ediyoruz.
Kortuk

@Mark - Katılıyorum. Bu benim için bir öğrenme süreci oldu.
J. Polfer

7

Evet, C ++ ile ilgili sorun, kodun artan ayak izidir.

Bazı sistemlerde bayt sayıyorsunuz ve bu durumda, sisteminizin sınırlarına yakın olan bir çalıştırma maliyetini kabul etmeniz gerekecektir.

Ancak, C'de bile, iyi tasarlanmış bir sistem için her şeyi kapalı tutmanız gerekir. İyi tasarlanmış sistemler zordur ve C ++ programcılara çok yapılandırılmış ve kontrollü bir geliştirme yöntemi için yer sağlar. OOP'yi öğrenmenin bir bedeli vardır ve eğer ona geçmek istiyorsanız, onu çok kabul ediyorsunuz, ve çoğu durumda yönetim C ile devam etmeyi tercih eder ve bir anahtarın sonuçlarını ölçmek zor olduğu için maliyeti ödemek istemez. verimliliği arttırır. Burada gömülü sistemler gurusu Jack Ganssle tarafından bir makale görebilirsiniz .

Dinamik hafıza yönetimi şeytandır. Gerçekten, şeytan otomatik rotada, dinamik bellek yönetimi bir bilgisayarda harika çalışıyor, ancak en azından birkaç haftada bir bilgisayarı yeniden başlatmayı bekleyebilirsiniz. Gömülü bir sistem 5 yıl boyunca çalışmaya devam ettiğinden, dinamik bellek yönetiminin gerçekten berbat olabileceğini ve gerçekten başarısız olmaya başladığını göreceksiniz. Ganssle, makalesinde yığın ve yığın gibi şeyleri tartışıyor.

C ++ 'da sorunlara neden olan ve daha fazla kaynak kullanan, dinamik bellek yönetimini kaldıran bazı şablonlar var ve şablonlar C ++' ı ayak izini C 'nin ayak izine daha yakın tutmak için büyük adımlardır. bellek yönetimi veya iyi C ++ yazmak için şablonlar. İstisnaları kaldırdıklarının farkına varmadım, istisnaları, kodumun yayın sırasında kaldırdığım önemli bir parçası olarak kabul ediyorum, ancak o ana kadar kullanıyorum. Alan testinde, istisnalar bana, yakalanılan bir istisna hakkında bilgi verecek mesajlar üretebilir.


1
Kod ayak izinin bir sorun olduğu konusunda hemfikirdim, ancak son zamanlarda flaş boyutunun bir mikrodenetleyicinin fiyatı üzerinde çok az bir etkisi olduğu, RAM boyutundan veya IO pinlerinin sayısından çok daha az olduğu görülüyor.
Wouter van Ooijen

Dinamik bellekteki argüman IMO için daha önemlidir. Durmaksızın haftalarca çalışabilen endüstriyel sistemler gördüm, ancak tanılama katmanı (C ++ ile yazılmış) yeniden başlama süresini yaklaşık 12 saatle sınırlar.
Dmitry Grigoryev

6

Linus Torvalds'ın bu anti-C ++ rantının ilginç olduğunu düşündüm .

C ++ 'ın mutlak en kötü özelliklerinden biri, bir çok şeyi o kadar bağlama nasıl bağımlı hale getirdiğidir - bu sadece koda baktığınızda, yerel bir görüşün nadiren ne olduğunu bilmek için yeterli bağlamı sağladığı anlamına gelir.

Yerleşik sistemler dünyası hakkında değil, Linux çekirdeği gelişimi hakkında konuşuyor. Bana göre, alaka düzeyi bundan kaynaklanıyor: C ++ daha geniş bir bağlamı anlamayı gerektiriyor ve bir dizi nesne şablonu kullanmayı öğrenebilirim, kodu birkaç ay içinde güncellemem gerektiğinde bunları hatırlamak için kendime güvenmiyorum.

(Öte yandan, şu anda Python (C ++ değil, aynı OOP paradigmasını kullanarak) kullanan ve tam olarak bu soruna sahip olan gömülü bir cihaz üzerinde çalışıyorum. Savunmamda, PC olarak adlandırılabilecek kadar güçlü bir gömülü sistem var. 10 yıl önce.)


5
Farklı olabiliriz, ancak herhangi bir projeyi açmanın hemen ne olduğunu söyleyemeyeceğimi anlıyorum, ancak ne yaptığı hakkında bir şey biliyorsam ve C de iyi kodlanmış bir şeye sahipsem ve C ++ 'da iyi kodlanmış bir şey varsa C ++ her zaman daha fazla görünüyor açık. Yine de C ++ 'ın yapması çok kolay olan C de iyi gelişme için kapsülleme uygulamanız gerekir. Sınıfların doğru kullanımı, arayüzlerin nerede olduğunuzu çok net bir şekilde ortaya koyabilir ve bir nesnede tamamen ele alınabilir.
Kortuk

Tamamen kapsülleme ve sınıflar üzerinde anlaştılar. Operatör aşırı ve kalıtım, çok değil.
ping,

1
Haha, evet, operatörün aşırı yüklenmesi, kodun fonksiyonunu engellemek için kullanılabilir. Birisi operatörün aşırı yüklenmesi durumunda, bunun açık sebeplerden olması veya hiç yapılmaması gerekir. Kalıtım, yalnızca bazı eklemeler içeren ebeveyn gibi bir şey yaptığınız belirli durumlarda kullanılmalıdır. Sanırım OOP'ta her iki işlevi de kullanmam. Her ikisini de kullandım, ancak gömülü bir sistemde olacağımı düşünemedim. Tıpkı değişken isimlerinde 80 karakter sınırına sahip bir derleyicinin derhal hurdaya çıkarılması gerektiğini düşünüyorum.
Kortuk

2
Az önce Python’da bir MCU’yu programlama düşüncesiyle ağzıma kustum.
vicatcu

Sadece sen değilsin, ama iyi çalışıyorsa ve verimli olursa, affedebilirim.
Kortuk

6

Diğer cevapların lehte ve aleyhte olanlar ve karar faktörleri için oldukça iyi bir durum olduğunu düşünüyorum, bu yüzden sadece birkaç yorum ekleyip eklemek istiyorum.

Küçük mikrodenetleyiciler için (8-bit) mümkün değil. Sadece kendine zarar vermek istiyorsun, kazanç yok ve çok fazla kaynak pes ediyorsun.

İyi bir işletim sistemine sahip üst düzey mikro denetleyiciler (örneğin, 32-bit, 10 veya 100 MB) ve tamamen iyi bir işletim sistemi olan Tamam, ve hatta tavsiye bile etmeye cüret ediyorum.

Öyleyse soru şudur: Sınır nerede?

Bundan emin değilim, ama bir keresinde C ++ 'ta 1 MB RAM ve 1 MB depolama alanlı 16 bit bir uC için bir sistem geliştirdim, ancak daha sonra pişman olmak için. Evet, işe yaradı, ama yaptığım ekstra iş buna değmezdi. Sığdırmak zorunda kaldım, istisnalar gibi şeylerin sızıntı yaratmayacağından emin olun (OS + RTL desteği oldukça sıkıcı ve güvenilmezdi). Dahası, bir OO uygulaması tipik olarak çok sayıda küçük tahsisler yapar ve bunlar için kullanılan yığın başka bir kabustur.

Bu deneyim göz önüne alındığında, gelecekteki projeler için yalnızca en az 16-bit ve RAM ve depolama için en az 16 MB olan sistemlerde C ++ 'ı seçeceğimi farz ediyorum. Bu keyfi bir sınırdır ve muhtemelen uygulama türü, kodlama stilleri ve deyimler vb. Şeylere göre değişecektir. Ancak uyarılar dikkate alındığında, benzer bir yaklaşım öneriyorum.


2
Buraya katılmamalıyım, sistem kaynaklarından dolayı C ++ 'nın kabul edilebilir olduğu ani bir nokta değil, iyi tasarım uygulamaları C ++' nın ayak izinin olduğu yerde ayak izini tutabilir. Bu, aynı alanı alan OOP tasarımları ile kodlanır. Kötü yazılmış C kadar kötü olabilir.
Kortuk

1
Bu, uygulamanızın ne kadar büyük olduğuna ve daha fazla alan gerektiren belirli özellikleri ne kadar kullandığınıza (şablonlar ve istisnalar gibi) bağlıdır. Ama şahsen, kendimi kısıtlanmış bir C ++ ile sınırlamak yerine C'yi kullanmayı tercih ederim. Ama o zaman bile daha büyük bir RTL'nin yükü, sanal yöntem tıkanıklıkları, yapıcı / yıkıcı zincir çağrısı olacak ... bu etkiler dikkatli kodlama ile hafifletilebilir, ancak daha sonra C ++ kullanımı, soyutlama ve üst düzey bakış açısı.
fceconel

4

Gömülü sistemlerde yararlı olan bazı C ++ özellikleri vardır. İstisnalar gibi pahalı olabilecek ve maliyetleri her zaman belli olmayan başkaları da var.

Ağzımı çalıştıysam, her iki dünyanın da en iyisini birleştiren ve her iki dilde olmayan bazı özellikler içeren popüler bir dil olurdu; bazı satıcılar bu özelliklerden bir kaçı içermektedir, ancak standartlar yoktur. Görmek istediğim birkaç şey:

  1. İstisnaları biraz daha fazla kullanıp, istisnalar atabilen veya sızdırabilen işlevlerin böyle bildirilmesi gereken Java gibi. Bu tür beyanlar için bir gereklilik programlama perspektifinden biraz rahatsız edici olsa da, bir fonksiyonun başarılı olması durumunda başarılı bir şekilde tamsayı döndürdüğü, ancak başarısız olabileceği durumlarda kodun netliğini artıracaktır. Pek çok platform, örneğin bir sicilde geri dönüş değerine ve taşıma bayrağındaki başarı / başarısızlık göstergesine sahip olarak bunu kodda uygun şekilde ele alabilir.
  2. Yalnızca statik ve satır içi işlevlerin aşırı yüklenmesi; Benim anladığım kadarıyla, C standart standartları, isim yönetimine ihtiyaç duyulmaması için fonksiyon aşırı yüklenmesinden kaçındı. Statik ve satır içi işlevlerin aşırı yüklenmesine izin vermek yalnızca bu sorunu önler ve harici işlevlerin aşırı yüklenmesinin% 99.9'unu verir (.h dosyaları satır içi aşırı yükleri farklı adlandırılmış harici işlevler açısından tanımlayabildiğinden).
  3. Keyfi veya belirli bir derleme zamanı ile çözülebilir sabit parametre değerleri için aşırı yükler. Bazı işlevler, sabit bir değerle iletildiğinde çok verimli bir şekilde satır içi, ancak bir değişken geçirildiğinde çok zayıf satır içi olabilir. Bir değer sabitse optimizasyon olabilecek diğer zamanlar kodu eğer değilse sabit olabilir. Örneğin:
    satır içi geçersiz copy_uint32s (uint32_t * dest, const uint32_t * kaynak, __is_const int n)
    {
      eğer (n <= 0) dönüş;
      Aksi takdirde (n == 1) {dest [0] = src [0];}
      aksi takdirde (n == 2) {dest [0] = src [0]; dest [1] = src [1];}
      aksi takdirde (n == 3) {dest [0] = src [0]; dest [1] = src [1]; dest [2] = src [2];}
      aksi takdirde (n == 4) {dest [0] = src [0]; dest [1] = src [1]; dest [2] = src [2]; dest [3] = src [3];}
      başka memcpy ((void *) dest, (const void *) src, n * sizeof (* src));
    }
    
    Derleme zamanında 'n' değerlendirilebilirse, yukarıdaki kod memcpy çağrısından daha verimli olacaktır, ancak 'n' derleme zamanında değerlendirilemezse, üretilen kod koddan çok daha büyük ve daha yavaş olacaktır. memcpy denir.

C ++ 'nın babasının sadece C ++' ın gömülü sürümünde çok istekli olmadığını biliyorum, ama sadece C kullanarak bazı önemli gelişmeler sunabileceğini düşünüyorum.

Herhangi bir standart için yukarıdakilere benzer bir şey yapılıp yapılmadığını bilen var mı?



@Joby Taffey: Yazımı, C ++ 'nın yaratıcısının gömülü bir alt kümeye istekli olmadığından bahsetmemesi için değiştirdim; Çabaların olduğunun farkındayım, fakat benim anladığım kadarıyla o kadar da bir şey alamadılar. 8 bit işlemcilere uygun olan standart bir dil için kesin bir kullanım olacağını ve yukarıda açıkladığım gibi özelliklerin herhangi bir platformda yararlı olacağını düşünüyorum. Yukarıda # 3 gibi şeyler sunan herhangi bir dil duydunuz mu? Çok faydalı gözüküyordu, ama hiçbir zaman bir dil önerdiğini görmedim.
supercat,

“C ++ 'ın babası gömülü sistemler programlamada sıfır deneyime sahiptir, peki neden onun fikrini önemseyelim?
Lundin,

@Lundin: Bazı etkili insanların çeşitli konulardaki görüşlerini önemsemediği gerçeği, başkalarının yapması için kendi başına bir sebep gibi görünecek. Yukarıdakileri yazdığımdan beri, şablonların artan gücünün, derleme zamanında hangi sabitlerin çözülebileceğine bağlı olarak aşırı yüklerin yüklenmesi için yeni olasılıklar ekleyebileceğini düşünüyorum; zaman özelliği (anladığım kadarıyla, çeşitli şeyleri sırayla denemeli ve başarısız olmayan
birinciyle

... ancak bu, derleyicinin daha sonra atılacak olan potansiyel ikameleri derlemek için oldukça fazla çaba harcamasını gerektirecektir. Daha açık bir şekilde söyleyebilmek, "Bu bir sabitse, bunu yapın; aksi halde bunu" herhangi bir "yanlış başlangıç ​​olmadan" yapın, daha temiz bir yaklaşım gibi görünecektir.
supercat,

3

C ++ birden fazla programlama dilidir:

a) Bu bir "daha iyi" C b) Nesne yönelimli bir dil c) Genel programlar yazmamıza izin veren bir dil.

Bu özelliklerin tümü ayrı ayrı kullanılabilse de, ikisi aynı anda kullanıldığında en iyi sonuçlar elde edilir. Bununla birlikte, yalnızca bir tanesini seçmeyi seçerseniz gömülü yazılımın kalitesi artacaktır.

a) "Daha iyi" bir C

C ++ güçlü bir yazı dilidir; C'den daha güçlü. Programlarınız bu özellikten yararlanacaktır.

Bazı insanlar işaretçilerden korkar. C ++ referansları içerir. Aşırı yüklenmiş fonksiyonlar.

Ve söylemeye değer: Bu özelliklerin hiçbiri daha büyük veya daha yavaş programlarda ortaya çıkmaz.

b) Nesne yönelimli bir dildir.

Birisi bu yazıda, mikrodenetleyicilerde makineyi soyutlamanın iyi bir fikir olmadığını söyledi. Yanlış! Hepimiz, gömülü mühendisler, makineyi her zaman soyutladık, sadece C ++ 'nın diğer sintaksıyla. Bu argümanla gördüğüm sorun, bazı programcıların nesnelerde düşünmeye alışık olmadıkları, bu şekilde OOP'un yararlarını göremedikleri.

Bir mikrokontrolörün çevre birimini kullanmaya hazır olduğunuzda, çevre biriminin aygıt sürücüsü biçiminde (kendiniz veya bir üçüncü tarafça) bizim için soyutlanmış olması muhtemeldir. Daha önce de söylediğim gibi, bir sonraki örneğin gösterdiği gibi (doğrudan bir NXP LPC1114 örneğinden alınmış) bu sürücü C sintaksını kullanıyor:

/ * TICKRATE_HZ * / de eşleşme ve kesme için zamanlayıcı ayarları

Chip_TIMER_Reset (LPC_TIMER32_0);

Chip_TIMER_MatchEnableInt (LPC_TIMER32_0, 1);

Chip_TIMER_SetMatch (LPC_TIMER32_0, 1, (timerFreq / TICKRATE_HZ2));

Chip_TIMER_ResetOnMatchEnable (LPC_TIMER32_0, 1);

Chip_TIMER_Enable (LPC_TIMER32_0);

Soyutlamayı görüyor musun? Böylece, aynı amaç için C ++ kullanıldığında, C ++ 'nın soyutlama ve kapsülleme mekanizması ile sıfır maliyetle soyutlama bir sonraki seviyeye getirilir!

c) Genel programlar yazmamızı sağlayan bir dildir.

Genel programlar, şablonlar aracılığıyla gerçekleştirilir ve şablonların programlarımız için de maliyeti yoktur.

Ayrıca, şablonlarla statik polimorfizm elde edilir.

Sanal yöntemler, RTTI ve istisnalar.

Sanal yöntemleri kullanırken bir uzlaşma var: performansta bir miktar para cezası yoksa daha iyi bir yazılım. Ancak, dinamik bağlanmanın sanal bir tablo (bir işlev işaretçisi dizisi) kullanılarak uygulanmasının muhtemel olduğunu unutmayın. Aynı şeyi C de birçok kez yaptım (düzenli olarak bile), bu yüzden sanal yöntemleri kullanmanın sakıncalarını göremiyorum. Dahası, C ++ 'da sanal yöntemler daha şık.

Son olarak, RTTI ve istisnalar hakkında bir öneri: Gömülü sistemlerde KULLANMAYIN. Onları ne pahasına önlemek !!


2

Geçmişim, gömülü (mcu, pc, unix, diğer), gerçek zamanlı. Emniyet açısından kritik. STL'ye daha önceki bir işveren tanıttım. Bunu artık yapmıyorum.

Bazı alev içeriği

C ++ gömülü sistemler için uygun mu?

Meh. C ++ yazması gereken bir acı ve sürdürülmesi gereken bir acıdır. C + sırayla tamam (bazı özellikleri kullanmayın)

Mikrodenetleyicilerde C ++? RTOSes? Ekmek Kızartma? Gömülü PC'ler?

Yine Meh dedim. C + çok fena değil, ancak ADA daha az acı veriyor (bu gerçekten bir şeyler söylüyor). Benim gibi şanslıysan, gömülü Java'yı yapmalısın. İşaretli dizi erişimi ve işaretçi aritmetik olmaması çok güvenilir kodlar yapar. Gömülü Java'daki çöp toplayıcıları en yüksek önceliğe sahip değildir ve genişletilmiş bellek ve nesnenin yeniden kullanımı vardır, bu nedenle iyi tasarlanmış kod GC olmadan sonsuza dek çalışabilir.

Mikroişlemcilerde OOP faydalı mı?

Tabii ki. UART bir nesnedir .... DMAC bir nesnedir ...

Nesne Devlet makineleri çok kolaydır.

C ++ programlayıcıyı etkin olmak için donanımdan çok uzakta tutar mı?

PDP-11 olmadığı sürece C sizin işlemciniz değildir. C ++ başlangıçta C'nin ön işlemcisiydi, bu nedenle Bjarne Stroustrup, AT&T'deyken Simula simülasyonlarının yavaş olması için güldü. C ++ sizin CPU'nuz değil.

Java bytecodes çalışan bir MCU gidin. Java'da bir program. C adamlarına gül.

Arduino'nun C ++ 'ı (dinamik bellek yönetimi olmadan, şablonlar, istisnalar hariç) "gerçek C ++" olarak mı düşünülmeli?

Hayır! MCU'lar için olduğu gibi tüm piç kurusu C derleyicileri gibi.

İleri, Gömülü Java veya Gömülü ADA standardize edilmiştir (ish); diğer her şey üzüntüdür.


2
Java'yı destekleyen mikro denetleyicileri bulmak kolay mı? Bunun seçimleri önemli ölçüde sınırlayacağını düşünüyorum. Ve performans cezası konusundaki deneyimleriniz nelerdir (uC’lerde genellikle JIT’ye sahip olmazsınız? GC'nin tahmin edilemezliğinin gerçek zamanlı sistemler üzerindeki etkisi ne durumda?
fceconel

2
Gömülü Java'yı destekleyen hangi MCU'lar var?
J. Polfer

Yeni başlayanlar için www.ajile.com.
Tim Williscroft

Ada için +1. Arduinos da dahil olmak üzere, içinde gömülü olarak çok şey var.
Brian Drummond,

c ile yazılmış mikroskoplar için portatif java VM açık kaynak kodludur. dmitry.co/index.php?p=./04.Thoughts/…
Tim Williscroft

-2

Gömülü sistemler, çoklu görevler için genel amaçlı bir bilgisayar olmak yerine, belirli bir görevi yerine getirmek için tasarlanmıştır. Gömülü bir sistem, bilgisayar donanımı ve yazılımı birleşimidir. C, tüm modern dillerin annesidir. Düşük seviyededir ancak tam dili güçlendirir ve her türlü donanıma sahiptir. Bu nedenle, C / C ++, gömülü sistemler için yazılım geliştirmek için en uygun seçimdir, ki bu da gömülü sistemler için çok kullanımıdır. Bildiğimiz gibi, C, gelişen bir dildir. UNIX işletim sistemi C ile yazılmıştır. Başarılı bir yazılım geliştirme, belirli bir proje için en iyi dili seçmekle ilgili sık sık olduğu için, C / C ++ dilinin hem 8 bit hem de 64 bit işlemciler için uygun olduğunu kanıtlaması şaşırtıcıdır. ; Bayt, kilobayt ve megabayt belleğe sahip sistemlerde. C işlemci bağımsızlığından yararlanıyor, programcıların belirli işlemci mimarisinin ayrıntılarına değil, algoritmalara ve uygulamalara odaklanmalarına olanak sağlar. Bununla birlikte, bu avantajların birçoğu diğer üst düzey dillere eşit olarak uygulanır. Fakat C / C ++, birçok dilin büyük ölçüde başarısız olduğu yerlerde başarılı oldu mu?


6
Bunun tartışmaya ne kattığını gerçekten emin değilim.
Dave Tweed

-3

<Rant>

C ++ ilk etapta berbat bir dil olduğunu düşünüyorum. OOP kullanmak istiyorsanız, Java programları yazın. C ++ OOP paradigmalarını zorlamak için hiçbir şey yapmaz, çünkü doğrudan bellek erişimi (ab) kullanımınız için tamamen sizin gücünüzdür.

Bir MCU'nuz varsa, büyük olasılıkla 100kB'den daha az flash bellekten bahsediyorsunuz. Hafızanın özeti olan bir dilde programlama yapmak istersiniz: Bir değişken veya dizi bildirdiğimde, bellek alır; malloc (C ++ 'da "yeni" anahtar kelime), programın başlatılması sırasında nadiren karşılaşılan durumlar dışında, gömülü yazılımlarda kullanımın az çok yasaklanması gerekir.

Cehennem, C'nin yeterince düşük olmadığı gömülü programlamada (sık sık) zamanlar vardır ve değişkenleri kayıtlara ayırmak ve kesme hizmet rutinlerinizi (ISR'leri) sıkmak için satır içi derleme yazmak gibi şeyler yapmanız gerekir. "Uçucu" gibi anahtar kelimeler anlaşılması oldukça önemli hale geldi. Zamanınızın çoğunu , nesne düzeyinde değil, bit düzeyinde belleği işlemek için harcarsınız .

Neden bazı şeylerin aslında olduklarından daha basit olduğunu düşünerek kendinizi kandırmak istiyorsunuz?

</ Rant>


Buradaki meselem basit, neden arabirim üzerinde tam olarak geliştirildiyse USART1'i kontrol etmek için yazılmış sürücünün karmaşıklığını bilmek istiyorum.
Kortuk

1
Size oy vermedim, ancak C ++ 'nın OOP'yi uygulamak zorunda olmadığına, sadece bunu yapmak için araçlar sağladığına işaret etmek istiyorum. İyi kodlama standartlarını uygulamak, geliştiricinin işidir. Dil kolaylaştırırsa yardımcı olabilir, ancak dil kendi başına asla yapmaz. Bazı durumlarda C okunamayabilir.
Kortuk

1
Tüm diller bir şey için iyidir. C ++ hızlı. OOP, iyi yapıldığında, birden fazla geliştiricinin paralel çalışmasını ve bilinmeyeni kodlamasını çok daha kolaylaştırır. Bence oyun geliştirmede bu kadar çekiş gücü var.
Toby Jaffey

1
Evet katılıyorum. Bunu gömülü dünya için görmemin sebebi, halihazırda mevcut olan farklı sistemlerin ve yeni sistemlerin geliştirilmesinde çok fazla özellik ve fonksiyonun eklenmesinden kaynaklanıyor. Proje büyüyor ve büyüyor. Ya onları geliştirmek daha uzun sürüyor ya da CS dünyasının PC'lerde ne yaptığını uygulamaya ve anlatmaya başladık.
Kortuk

5
C ++ 'ı tam olarak anlamayan başka biri. Kaç tane olduğunu herzaman beni şaşırtıyor.
Rocketmagnet
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.