Standardı takip etmek, bu konuda C standardını almak gerekli mi?


17

Stack Overflow'da her zaman C standardı hakkında konuşan çok deneyimli insanlar var. İnsanlar benim için çalışıyor olsalar bile taşınabilir olmayan çözümleri sevmiyor gibi görünüyor. Tamam, standardın takip edilmesi gerektiğini anlıyorum, ancak programcının yaratıcılığına pranga koymuyor mu?

Bir standardı takip etmenin getirdiği somut faydalar nelerdir? Özellikle derleyiciler standardı biraz farklı uygulayabildiğinden.


7
Ne demek istediğini "standart" olarak açıklayabilir misin? Standart tarafından tanımlanmayan davranışlara tepki vermemeyi mi kastediyorsunuz? Veya uzantı / derleyici özelliklerini kullanmıyor musunuz? Veya stil kuralları?
ikh

1
@ikh ISO C standartlarını (C90, C99, C11) alıyor.
Aseem Bansal

9
Bu, İngilizce dilbilgisi ve kelime bilgisini kullanarak İngilizce yazmanın veya konuşmanın yaratıcılığınıza pranga koyduğunu söylemekle aynı şeydir. Elbette, insanlar kurallara uyarak, tutarlılık pahasına harika şeyler yapabilirler, ancak yine de İngilizcenin "standardına" bağlı kalırken milyonlarca yaratıcı kitap yazabilirsiniz.
Avner Shahar-Kashtan

"İnsanlar benim için çalışıyor olsalar bile taşınabilir olmayan çözümler gibi görünmüyor" diye bir örnek ekleyebilir misiniz?
BЈовић

1
@PHIfounder Sadece bu son durumu ele almak için, ana dönüşü atlayabilirsiniz, dolaylı olarak 0 döndürür :)
Daniel Gratzer

Yanıtlar:


45

Standarda bağlı kalmanın iyi bir şey olmasının birkaç nedeni vardır.

  1. Bir derleyiciye kilitli olmak zor. Tamamen kendi gündemine sahip bir grup geliştiricinin merhametindesiniz. Açıkçası sizi ya da herhangi bir şeyi almak için dışarı değiller, ancak derleyiciniz optimizasyonlara, yeni özelliklere, güvenlik düzeltmelerine vb. Sıkıştın. Aşırı durumlarda, bazı şirketler kendilerini bağımlı kılan herhangi bir aracı yamalamaya başlamak zorundadır. Bu, orada başka çalışma araçları olduğunda büyük bir para ve zaman kaybıdır.

  2. Bir platforma kilitlenmiş olmak daha zordur. Linux'a yazılım yüklüyorsanız ve pazarınızın gerçekten orada olduğunu fark ettiğiniz için Windows'a geçmek istiyorsanız, güzel oynamak için kodunuzdaki taşınabilir olmayan her kesmek değiştirmenin bir zamanı olacak hem GCC hem de MSVC ile. Çekirdek tasarımınızın böyle bir şeye dayalı birkaç parçanız varsa, iyi şanslar!

  3. Geriye dönük uyumsuz değişiklikler en zoru emer. Standart asla kodunuzu kırmaz (Python'u yoksay). Bazı rastgele derleyici yazarı, gerçekten bu uygulamaya özel eklentinin sorun olmayacağına karar verebilir ve bırakabilir. Eğer ona güvenirseniz, o zaman en son hangi eski modası geçmiş versiyona takılı kalırsınız.

Bu nedenle, burada geçerli olan mesaj , standarda bağlı kalmak sizi daha esnek hale getirir . Daha sınırlı bir diliniz var ama daha çok diliniz var

  • Kütüphaneler
  • Destek (insanlar standardı bilir, derleyiciye özgü her karmaşık hack değil)
  • Mevcut platformlar
  • Olgun araçlar
  • Güvenlik (gelecekteki ispat)

Hassas bir denge, ancak standardı tamamen görmezden gelmek kesinlikle bir hatadır. Taşınabilir olmayan bir şekilde uygulanabilecek soyutlamalara güvenmek için C kodumu düzenleme eğilimindeyim, ancak soyutlamaya bağlı olan her şeyi değiştirmeden şeffaf bir şekilde bağlantı kurabiliyorum.


+1 adil yeterli :), teşekkürler ... Derleyicilerin standartlardan biraz sapma ve beni kesinlikle takip etme konusunda şüpheci hissetmeme, artılarını ve eksilerini bilmem gerekiyordu ve bunları açıkça tanımladım.
0Aralık0

6
Tanımsız davranış muhtemelen biraz da berbat. C ile standardı yakından takip etmezseniz UB'ye girmek oldukça kolaydır.
CodesInChaos

@CodesInChaos Kabul etti, tanımlanmamış davranış bir yandan harika, çünkü bazı çılgın optimizasyonlara izin veriyor, ancak diğer yandan hata
ayıklıyor

6

Standart, sizinle derleyiciniz arasında programlarınızın anlamını tanımlayan bir tür "sözleşme" dir. Programcılar olarak, genellikle dilin nasıl çalıştığına dair belirli bir zihinsel modelimiz vardır ve bu zihinsel model genellikle standartla çelişmektedir. (Örneğin, C programcıları genellikle bir işaretçiyi kabaca "bir bellek adresini gösteren bir tam sayı" olarak düşünür ve bu nedenle, bir belleği gösteren bir tamsayı ile gösterebilecek işaretçiler üzerinde herhangi bir aritmetik / dönüşüm / manipülasyon gerçekleştirmenin güvenli olduğunu varsayarlar. Bu varsayım standarda uymuyor; aslında işaretçilerle neler yapabileceğiniz konusunda çok katı kısıtlamalar getiriyor.)

Peki, kendi zihinsel modelinizden ziyade standardı takip etmenin avantajı nedir?

Basitçe söylemek gerekirse, standart doğru ve kendi zihinsel modeliniz yanlış. Zihinsel modeliniz genellikle, tüm durumlarda derleyici optimizasyonları devre dışı bırakıldığında, şeylerin kendi sisteminizde nasıl çalıştığına dair basitleştirilmiş bir görünümdür; derleyici satıcıları, özellikle de optimizasyonlar söz konusu olduğunda, genellikle buna uyma çabası göstermezler. (Sözleşmenizin sonunu tutmazsanız, derleyiciden belirli bir davranış bekleyemezsiniz: garbage in, garbage out.)

İnsanlar benim için çalışıyor olsalar bile taşınabilir olmayan çözümleri sevmiyor gibi görünüyor.

" Benim için çalışıyor gibi görünseler bile" demek daha iyi olabilir . Derleyiciniz belirli bir davranışın işe yarayacağını özellikle belgelemedikçe (yani: standart uygun artı derleyici belgelerinden oluşan zenginleştirilmiş bir standart kullanmıyorsanız), gerçekten işe yaradığını veya gerçekten güvenilir olduğunu bilmezsiniz. Örneğin, işaretli tamsayı taşması tipik olarak birçok sistemde sarma ile sonuçlanır ( INT_MAX+1tipik olarak INT_MIN) - derleyicilerin işaretli tamsayı aritmetiğinin (doğru) bir C programında asla taşmadığını ve genellikle buna dayalı olarak çok şaşırtıcı optimizasyonlar gerçekleştirdiğini "bilmesi" bilgi".


1
Derleyebilirsiniz -fwrapvve daha sonra işaretli tam sayı aritmetiğinin her zaman sarıldığı biraz farklı, standart olmayan bir dil kullanırsınız.
user253751

@immibis: C89 yazıldığında, mantıksal dokümanına göre, çağdaş derleyicilerin çoğunluğu tamsayı taşması için sessiz sarma semantiği tanımladı. Çoğu durumda, tamsayı taşması durumunda neler olacağına dair bir çeşit garantiye sahip olmak, özellikle garantiler kesin sarma davranışını zorunlu kılacak kadar ilerlemezse, kodun bu tür garantiler olmadan mümkün olandan daha verimli olmasına izin verebilir [hassas kaydırma davranışı imzasız matematik kullanılarak taklit edilebilir, ancak daha gevşek olan ancak gereksinimleri karşılamak için hala yeterli olan semantikler daha verimli koda izin verebilir].
supercat

@immibis: Revizyonistlerin insanları belirli platformlar için derleyiciler arasında neredeyse oybirliğiyle uygulanan davranışların (veya bazı durumlarda% 100 oybirliğiyle) bu tür platformlarda asla "standart" olmadığına ikna edebilmeleri çok kötü. bu tür davranışlardan kaçınmaktan kaynaklanan verimlilik kaybı, bir derleyicinin bunları iptal ederek başarabildiği hiçbir "optimizasyon" ile telafi edilmeyecektir.
supercat

4

Standardın takip edilmesi gerektiğini anlıyorum, ancak programcının yaratıcılığına pranga koymuyor mu? farklı derleyicilerin standartları takip etme tarzında hala bazı farklılıklar vardır. Örneğin, performans ve hız açısından çok iyi, yani tüm önemli olan bir kod yazabilirim, ancak yine de standartları kesinlikle takip etmeyebilir.

Hayır. Standart, ne yapmasına izin verildiğini söyler. Belirtilmezse, tanımlanmamış davranış bölgesindesiniz ve daha sonra tüm bahisler kapalıdır - program herhangi bir şey yapmakta serbesttir.


Eğer belirli bir örnek söz yana void main()VS int main(), benim cevap artırabilir.

void main()ana işlevin standart bir açıklaması değildir. Bazı derleyiciler üzerinde uzantılarla çalışabilir, ancak uygulamaya dayanır. Çalışsa bile, istediğiniz şeyi yapıp yapmadığını kontrol etmeniz gerekir. Sorun şu ki, derleyici geliştiricileri bir void main()sonraki derleyici sürümü ile kaldırmaya karar verebilir ve uygulamanızı bozabilir .

Diğer yandan, standart ana imzayı açıkça tanımlar int main()ve ne yapması gerektiğini söyler.


Öte yandan, standartta tanımlanmayan şeyler var. Ardından başka bir standart uygulanabilir (örneğin, POSIX gibi). En iyi örnek, c ++ 03 standart programlarının 1 iş parçacıklı olması nedeniyle c ++ 03'teki iş parçacığı uygulamasında olabilir. Bu durumda, platforma bağlı kitaplığı veya boost gibi bir şeyi kullanmak zorunda kalırsınız .


4
Bir derleyicinin standart olmayan her şeyi tanımlanmamış davranış değildir, derleyici uzantıları belirleyici ve kasıtlı olmaları açısından iyi tanımlanmıştır. UB değil.
Daniel Gratzer

@jozefg Sorulma şekli - OP'nin UB uygulama şeklini düşündüğü açıktır. Örneğin, iş parçacıkları c ++ 03'te tanımlanmadı.
BЈовић

1
@deworde: Yorum yanıttan kaldırıldı.
Kevin

@jozefg Belirli bir derleyici her zaman imzalı tam sayıları sararsa, belgesiz bir dil uzantısı olarak düşünülebilir. (Elbette belgesiz olmak, uzantıyı kaldırmamaları konusunda hiçbir garantinizin olmadığı anlamına gelir)
user253751

-6

Projeniz özel projeler, örneğin bir gov projesi veya ordu projesi ise, kurallara uymayın, ancak açık kaynaklı veya dağıtılmış bir ekiple büyük bir projeden bahsediyorsanız, kurallara uymanız gerekir.


2
hiçbir açıklama yapmadan, başka birinin aksi görüş bildirmesi durumunda bu cevap işe yaramayabilir. Örneğin, birisi "projeniz özel projeler, örneğin bir gov projesi veya ordu projesi ise, kurallara uyun, ancak açık kaynaklardan bahsediyorsanız kurallara uymanız gerekmiyorsa" gibi bir talep gönderirse ... , bu cevap okuyucuya iki karşıt görüş seçmesine nasıl yardımcı olur? Düşünün düzenlemek daha iyi bir şekle ing
tatarcık

2
Bilinmeyen: gov projelerinde kaç standart olduğunu öğrenmek sizi şaşırtacak ...
Deer Hunter
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.