Derleyici uyarılarını neden her zaman etkinleştirmeliyim?


302

Sık sık C ve C ++ programları derlerken "her zaman derleyici uyarılarını etkinleştirmeliyim". Bu neden gerekli? Bunu nasıl yaparım?

Bazen "uyarıları hata olarak değerlendirmem" gerektiğini de duyarım. Yapmalımıyım? Bunu nasıl yaparım?

Yanıtlar:


341

Uyarıları neden etkinleştirmelisiniz?

C ve C ++ derleyicileri, bazı yaygın programcı hatalarını varsayılan olarak bildirirken kötü bir şekilde kötüdür :

  • bir değişkeni başlatmayı unutmak
  • returnbir fonksiyondan bir değeri unutmak
  • biçim dizesiyle eşleşmeyen bağımsız değişkenler printfve scanfaileler
  • bir işlev önceden bildirilmeden kullanılır (yalnızca C)

Bunlar saptanabilir ve rapor edilebilir, sadece varsayılan olarak değil; bu özellik derleyici seçenekleriyle açıkça istenmelidir.

Uyarılar nasıl etkinleştirilir?

Bu derleyicinize bağlıdır.

Microsoft C ve C ++ derleyicileri anahtarları gibi anlıyorum /W1, /W2, /W3, /W4ve /Wall. En azından kullanın /W3. /W4ve /Wallsistem başlık dosyaları için sahte uyarılar yayarlar, ancak proje bu seçeneklerden birine sahip temiz derler eğer, bunun için gidebilir. Bu seçenekler birbirini dışlar.

Diğer birçok derleyici -Wall, -Wpedanticve gibi seçenekleri anlar -Wextra. -Wallönemlidir ve geri kalan her şey önerilir (ismine rağmen hepsinin-Wall değil , yalnızca en önemli uyarıları etkinleştirdiğini unutmayın ). Bu seçenekler ayrı ayrı veya hepsi birlikte kullanılabilir.

IDE'nizin bunları kullanıcı arayüzünden etkinleştirmenin bir yolu olabilir.

Uyarıları neden hata olarak değerlendirmeliyim? Bunlar sadece uyarılar!

Derleyici uyarısı, kodunuzda potansiyel olarak ciddi bir soruna işaret eder. Yukarıda listelenen sorunlar neredeyse her zaman ölümcüldür; diğerleri olabilir veya olmayabilir, ancak yanlış alarm olduğu halde bile derlemenin başarısız olmasını istiyorsunuz . Her bir uyarıyı araştırın, temel nedeni bulun ve düzeltin. Yanlış alarm durumunda, etrafında çalışın - yani, uyarının artık tetiklenmemesi için farklı bir dil özelliği veya yapı kullanın. Bunun çok zor olduğu ortaya çıkarsa, söz konusu uyarıyı duruma göre devre dışı bırakın.

Hepsi yanlış alarm olsa bile uyarıları sadece uyarı olarak bırakmak istemezsiniz. Yayılan toplam uyarı sayısının 7'den az olduğu çok küçük projeler için uygun olabilir. Daha fazlası, yeni bir uyarının eski tanıdıklardan oluşan bir selde kaybolması kolaydır. Buna izin verme. Tüm projenizin temiz bir şekilde derlenmesine neden olun.

Bunun program geliştirme için geçerli olduğunu unutmayın. Projenizi kaynak formda dünyaya -Werroryayınlıyorsanız, yayınlanmış derleme betiğinizde tedarik veya eşdeğeri olmamak iyi bir fikir olabilir . İnsanlar projenizi derleyicinin farklı bir sürümüyle veya farklı bir uyarıcı kümesinin etkinleştirilmiş olabileceği farklı bir derleyiciyle oluşturmaya çalışabilirler. Yapılarının başarılı olmasını isteyebilirsiniz. Uyarı mesajlarını gören kişilerin size hata raporları veya yamalar gönderebilmesi için uyarıları etkin durumda tutmak iyi bir fikirdir.

Uyarılar hata olarak nasıl ele alınır?

Bu yine derleyici anahtarları ile yapılır. /WXMicrosoft içindir, diğerlerinin çoğu kullanır -Werror. Her iki durumda da, üretilen uyarılar varsa derleme başarısız olur.


107
Bu soru ve cevapları yayınladım çünkü insanlara uyarıları etkinleştirmelerini söylemekten bıktım ve yoruldum. Şimdi onları burada gösterebilirim (ya da özellikle kötü bir ruh halindeysem, sorularını bir dupe olarak kapatın). Bu cevabı geliştirebilir veya kendi cevabınızı ekleyebilirsiniz!
n. 'zamirler' m.


9
Ekleyeceğim tek değiştirici, bazı uyarıların uygulamanız için yararlı olmayabileceğidir. (Derleyicinin bir yapıdaki öğeler arasında 2 bayt dolgu eklediğine dair uyarılar gördüm. Uygulama prototip oluşturmak içindi, bu yüzden biraz boşa giden bellek bizi rahatsız etmedi.) Tüm uyarıları hata olarak ele alın ve ardından yalnızca bu uyarının size neden yardımcı olmadığını biliyorsunuz.
Kyle A

20
Varsayılan derleme talimatlarınızı izleyen uyarıları hata olarak değerlendirmenin dezavantajı, derleyici olarak kod çürümelerinizin yeni uyarılar eklemesidir. Kodunuzu indirip gelecekte oluşturmaya çalışan kullanıcılar, derleyicileri çok yeni olduğu ve bazı ekstra parantezler veya derleyicinizin umurunda olmadığı bir şey hakkında bir uyarı verdiği için yapamayabilir. Hatayla karşılaşan kullanıcı, kodunuzdan veya derleme sisteminizden sorumlu değildir ve uyarıları hata olarak ele almayı ve projenizi gerçekte nasıl oluşturacağınızı bilmiyor.
interfect

15
@interfect Evet, bu bana birkaç kez oldu. Biggie yok. Hiç test edilmemiş bir derleyici kullanarak bakımsız bir yazılım parçası oluşturmayı seçtiyseniz, kendiniz biraz bakım yapmaya hazır olsanız iyi olur.
n. 'zamirler' m.

94

C, ünlü olarak, HLL'ler gibi oldukça düşük seviyeli bir dildir. C ++, C'den oldukça yüksek düzeyde bir dil gibi görünse de, hala bazı özelliklerini paylaşmaktadır. Ve bu özelliklerden biri, dillerin programcılar, programcılar ve özellikle de ne yaptıklarını bilen programcılar için tasarlanmasıdır.

[Bu cevabın geri kalanı için C'ye odaklanacağım. Söyleyeceğim şeylerin çoğu C ++ için de geçerli, ancak belki de o kadar güçlü değil. Bjarne Stroustrup'un ünlü dediği gibi, "C kendinizi ayağınızı vurmayı kolaylaştırır; C ++ zorlaştırır, ancak bunu yaptığınızda tüm bacağınızı havaya uçurur." ]

Ne yaptığınızı biliyorsanız - gerçekten ne yaptığınızı bilirseniz - bazen “kuralları çiğnemek” gerekebilir. Ancak çoğu zaman, birçoğumuz iyi niyetli kuralların hepimizi beladan uzak tuttuğunu ve bu kuralları her zaman ahlaksız bir şekilde ihlal etmenin kötü bir fikir olduğunu kabul edeceğiz.

Ancak C ve C ++ 'da yapabileceğiniz şaşırtıcı bir şekilde "kötü fikirler" olan, ancak resmi olarak "kurallara aykırı" olmayan çok sayıda şey vardır. Bazen kötü bir fikir olabilirler (ama diğer zamanlarda savunulabilirler); bazen neredeyse her zaman kötü bir fikirdir. Ama gelenek her zaman bu şeyler hakkında uyarmak değildi - çünkü, yine, programcıların ne yaptığını bildikleri, bu şeyleri iyi bir sebep olmadan yapamayacakları, bir grup tarafından rahatsız olacakları varsayımı gereksiz uyarılar.

Ama elbette tüm programcılar ne yaptıklarını gerçekten bilmiyorlar. Özellikle, her C programcısı (ne kadar deneyimli olursa olsun) bir başlangıç ​​C programcısı olma aşamasından geçer. Ve deneyimli C programcıları bile dikkatsizleşebilir ve hata yapabilir.

Son olarak, deneyim sadece programcıların hata yaptığını değil, aynı zamanda bu hataların gerçek ve ciddi sonuçları olabileceğini göstermiştir. Bir hata yaparsanız ve derleyici sizi bu konuda uyarmazsa ve program bir şekilde derhal çökmez veya bundan dolayı açıkça yanlış bir şey yapmazsa, hata neden oluncaya kadar bazen yıllarca gizlenebilir. bir gerçekten büyük bir sorun.

Sonuçta, çoğu zaman uyarıların iyi bir fikir olduğu ortaya çıkıyor. Deneyimli programcılar bile, dengede, uyarıların zarardan daha iyi olma eğiliminde olduğunu öğrendi (aslında, " özellikle deneyimli programcılar öğrendi"). Kasten yanlış bir şey yaptığınızda ve uyarı bir sıkıntı verdiğinizde, yanlışlıkla en az on kez yanlışlıkla bir şey yaptınız ve uyarı sizi daha fazla sorundan kurtardı. Ve çoğu uyarı, "yanlış" şeyi gerçekten yapmak istediğinizde, birkaç kez devre dışı bırakılabilir veya geçici olarak çözülebilir.

(Böyle bir "hata" klasik bir örnek testidir if(a = b)eğer hatta bazıları varsayılan olarak Ama -. Çoğu zaman, bu bir hata, bu gün bu konuda uyarmak yüzden birçok derleyici olduğunu. Gerçekten hem ata istediği biçin ave test sonucu yazarak uyarıyı devre dışı bırakabilirsiniz if((a = b)).)

İkinci soru, neden derleyiciden uyarıları hata olarak ele almasını istemesiniz ki? Bunun insan doğası yüzünden olduğunu söyleyebilirim, özellikle de "Oh, bu sadece bir uyarı, o kadar önemli değil, bunu daha sonra temizleyeceğim." Ama eğer bir erteleyici iseniz (ve sizi tanımıyorum, ama ben korkunç bir erteleyiciyim), temelde her zaman mutlaka temizlemeyi ertelemek kolaydır - ve uyarıları göz ardı etme alışkanlığına girerseniz, görmezden geldiklerinizin ortasında, orada oturan önemli bir uyarı mesajını kaçırmak daha kolay ve daha kolay hale gelir .

Derleyiciden uyarıları hata olarak ele almasını istemek, bu insan foible'ı dolaşmak için kendiniz oynayabileceğiniz küçük bir numaradır.

Şahsen, uyarılara hata muamelesi yapmak konusunda ısrarcı değilim. (Aslında, dürüst olursam, "kişisel" programlamamda neredeyse hiçbir zaman bu seçeneği etkinleştirmediğimi söyleyebilirim.) Ama bu seçeneğin işyerinde etkinleştirildiğinden emin olabilirsiniz. yazdı) kullanımını zorunlu kılar. Ve söyleyebilirim ki - çoğu profesyonel programcı, C'deki hatalar olarak uyarıları tedavi etmeyen herhangi bir mağazanın sorumsuzca davrandığını, yaygın olarak kabul edilen endüstrinin en iyi uygulamalarına uymadığını söyleyebilirim.


9
"ne yaptıklarını bilen programcılar" - LOL; hiç
görmediysem

3
@Dancrumb LOL geri atcha. Gerçek İskoçyalı yanılgısını anladığımdan asla emin değilim , ama hoşuma gitti, bu yüzden bu benim için iyi bir egzersiz olacak. Sanırım buradaki uygulama şöyle: "Hiçbir C programcısı yazmazdı if(a = b), bu yüzden uyarmamız gerekmiyor." (. Sonra birileri bu özel hatadan sonucu olduğunu 10 yayımlanan ürünlerde 10 kritik hataların bir listesini üretir) "Tamam, hiçbir deneyimli C programcısı hiç yazardı ki ..."
Steve Zirvesi

3
@SteveSummit ama gerçekten deneyimli bir C programcısı if (returnCodeFromFoo = foo(bar)), kodu tek bir yerde yakalamak ve test etmek için yazabilir ve anlamına gelebilir ( Tek amacının fooyan etkilere sahip olduğunu varsayın !) Gerçekten çok deneyimli bir programcının bunun bir iyi kodlama tarzı noktanın yanındadır;)
alephzero

5
Mesele şu ki, en deneyimli programcılar çoğu olmasa da uyarıların çoğunu mümkün kılar. Eğer böyle bir şey kullanmak if (returnCodeFromFoo = foo(bar))istiyorlarsa, bir yorum yaparlar ve uyarıyı kapatırlar (böylece bakım programcısı 4 yıl sonra ona baktığında, kodun kasıtlı olduğunu anlar. (Microsoft C ++ ülkesinde) / Wall ile uyarıları hata olarak ele almanın bir yol olduğunu ısrar eden biriyle. Uh, değil (pek çok baskılama yorumu koymak istemiyorsanız).
Flydog57

3
Does birisi olarak değil günlük olarak yazma kodu, ama ne zaman bunu ben paha biçilmez uyarıları bulmak (genellikle kendi tasarım tahtasına) çıplak metal olma eğilimindedir. Dahili kayıtlara değerler doldururken (bir DMA tanımlayıcı konumu için örnek olarak) işaretçiye dönüştürme ile ilgili uyarı, uyarıyı temizlemek için bir döküm yaptığım anlamına gelir. Bu bir hata olmaz, ancak başka biri (hatta kendim!) Bu kodu birkaç ay içinde alırsa kafa karıştırıcı olabilir. Ayrıca, CAD araçlarımın çıktılarına da mevcut uyarı yok kuralı uyguluyorum.
Peter Smith

39

Uyarılar, en yetenekli C ++ geliştiricilerinin bir uygulamaya dönüştürebileceği en iyi tavsiyeden oluşur. Etrafında tutmaya değerler.

Bir Turing tam dili olan C ++, derleyicinin ne yaptığınızı bildiğinize güvenmesi gereken birçok duruma sahiptir. Ancak, derleyicinin muhtemelen yazdıklarınızı yazmak istemediğinizi anlayabileceği birçok durum vardır. Klasik bir örnek printf geçirilen bağımsız değişkenler veya std :: dizeleri eşleşmiyor printf () kodları (yani değil hiç benim başıma!). Bu durumlarda, yazdığınız kod bir hata değildir. Derleyicinin işlemesi için geçerli bir yorumu olan geçerli bir C ++ ifadesidir. Ancak derleyici, modern bir derleyicinin algılaması kolay bir şeyi gözden kaçırdığınız güçlü bir önsezi var. Bunlar uyarılar. Bunlar, derlemede, C ++ 'ın tüm katı kurallarını kullanarak gözden kaçırmış olabileceğiniz açık şeylerdir.

Uyarıları kapatmak veya yoksaymak, sizden daha yetenekli kişilerden gelen ücretsiz tavsiyeleri görmezden gelmeyi seçmek gibidir. Huberis'te güneşe çok yakın uçtuğunuzda ve kanatlarınız eridiğinde veya bir bellek bozulması hatası oluştuğunda biten bir ders. İkisi arasında her gün gökten düşeceğim!

"Uyarıları hata olarak değerlendir", bu felsefenin en uç versiyonudur. Buradaki fikir , derleyicinin size verdiği her uyarıyı çözmenizdir - her ücretsiz tavsiyeyi dinler ve ona göre hareket edersiniz. Bunun sizin için geliştirme için iyi bir model olup olmadığı, takıma ve ne tür bir ürün üzerinde çalıştığınıza bağlıdır. Bir keşişin sahip olabileceği çileci bir yaklaşım. Bazıları için harika çalışıyor. Diğerleri için değil.

Birçok uygulamamda uyarıları hata olarak değerlendirmiyoruz. Bunu yapıyoruz, çünkü bu belirli uygulamaların çeşitli yaşlarda çeşitli derleyicileri olan birkaç platformda derlenmesi gerekir. Bazen bir uyarıyı başka bir platformda uyarıya dönüştürmeden bir tarafa düzeltmenin aslında imkansız olduğunu görürüz. Bu yüzden sadece dikkatliyiz. Uyarılara saygı duyuyoruz, ancak onlar için geriye doğru eğilmiyoruz.


11
C ++ olmak Turing tam olan ne bununla ilgili. Birçok dil tamamlanıyor ve yanlış bir şey yaparsanız size güvenmiyorum ....
Güle güle SE

3
@KamiKaze her dilde deyimsel hatalar olacaktır (örneğin, Java tutarsız bir şekilde yazmanızı durduramaz equals/ hashCode) ve bunlardan hangisinin bildirildiği bir uygulama kalitesi sorunudur.
Caleth

2
@KamiKaze Turing tamlık biti, derleyicinin kodunuzun planlandığı gibi çalışamayacağını kanıtlayamadığı durumlar olduğunu gösterir. Bu önemlidir çünkü derleyiciler tüm "yanlış" kodları hata yapamazlar. Hatalar yalnızca dil tasarımcılarının her zaman "yanlış" olacağından emin oldukları davranışlar için ayrılabilir. (tipik olarak tutarsız yolları aşağı çekmesi nedeniyle).
Cort Ammon

2
Bu da "tüm uyarılar hatalardır" ile ilgili zorluğa işaret ediyor. Uyarılar, tasarım gereği, daha fırsatçıdır, yanlış kodu daha sık tetiklemek için potansiyel olarak doğru bazı kodları tetikler. Hata olarak uyarılar, dilin tüm yeteneklerini kullanamamanıza neden olur.
Cort Ammon

2
Ancak, genel olarak, programcılar "güvenli" bir şeyden fazlasını yapan bir dil ister. Yapmasını söylediğimizi düşündüğümüz şeyi yapan bir dil istiyoruz. Bu nedenle, uyarılar önemli olmaya devam etmektedir, çünkü bilgisayarın yapmasını istediğimiz gerçek sınıf sınıfı anlamsal bir sınıftır. Derleyici, "yanlış" veya "güvensiz" olarak tanımlayarak bunu kaldırabilir, ancak sonunda programcının programın yapmasını istediği davranışların bir üst sınıfına sahipsiniz. Uyarılar, üst sınıfın daraltılmasına yardımcı olur.
Cort Ammon

19

Sadece uyarıları yönetmek daha iyi kod yapmakla kalmaz, aynı zamanda daha iyi bir programcı yapar. Uyarılar size bugün size çok az görünebilecek şeyler hakkında bilgi verecektir, ancak bir gün kötü alışkanlık geri dönecek ve kafanızı ısırır.

Doğru türü kullanın, bu değeri döndürün, bu dönüş değerini değerlendirin. Zaman ayırın ve "Bu gerçekten bu bağlamda doğru tip midir?" "Bunu iade etmem gerekiyor mu?" Ve biggie; "Bu kod önümüzdeki 10 yıl boyunca taşınabilir olacak mı?"

İlk etapta uyarı içermeyen kod yazma alışkanlığını edinin.


17

Diğer cevaplar mükemmel ve söylediklerini tekrarlamak istemiyorum.

Düzgün bir şekilde dokunulmamış "uyarıları neden etkinleştir" in diğer bir yönü de kod bakımında çok yardımcı olmalarıdır. Önemli boyutta bir program yazdığınızda, her şeyi bir anda kafanızda tutmak imkansız hale gelir. Genellikle aktif olarak yazdığınız ve düşündüğünüz bir fonksiyonunuz veya üçünüz ve belki de ekranınızda başvurabileceğiniz bir dosya veya üçünüz vardır, ancak programın büyük kısmı arka planda bir yerde bulunur ve buna güvenmeniz gerekir. çalışmaya devam ediyor.

Uyarmak ve onları olabildiğince enerjik ve yüzünüzde bulundurmak, değiştirdiğiniz bir şey göremediğiniz bir şey için sorun çıkarırsa sizi uyarmaya yardımcı olur.

Örneğin, clang uyarısını ele alalım -Wswitch-enum. Bu, bir enum üzerinde bir anahtar kullanır ve olası enum değerlerinden birini kaçırırsanız bir uyarı tetikler. Bu, olası olmayan bir hata olacağını düşünebileceğiniz bir şey: muhtemelen en azından switch deyimini yazarken numara değerleri listesine baktınız. Hatta sizin için anahtar seçeneklerini oluşturan bir IDE'niz bile olabilir, bu da insan hatasına yer bırakmaz.

Bu uyarı, altı ay sonra sıralamaya başka bir olası giriş eklediğinizde gerçekten kendi başına gelir. Yine, eğer söz konusu kodu düşünüyorsanız muhtemelen iyi olacaksınız. Ancak bu numaralandırma birden fazla farklı amaç için kullanılıyorsa ve ekstra seçeneğe ihtiyacınız olanlardan biri ise, 6 ay boyunca dokunmadığınız bir dosyadaki bir anahtarı güncellemeyi unutmak çok kolaydır.

Uyarıları otomatik test senaryolarında düşündüğünüz şekilde düşünebilirsiniz: kodun mantıklı olduğundan emin olmanıza ve ilk yazdığınızda ihtiyacınız olanı yapmanıza yardımcı olurlar, ancak bunun siz bunu yaparken ihtiyaç duyduğunuz her şeyi yapmaya devam ediyor. Fark, test senaryolarının kodunuzun gereksinimlerine çok dar bir şekilde çalışması ve bunları yazmanız gerekirken, uyarılar hemen hemen tüm kodlar için makul standartlara göre geniş çapta çalışır ve derleyicileri yapan boffins tarafından çok cömertçe sağlanır.


9
Bakım konusunda yardımcı olmanın diğer yolu, başkasının koduna baktığınızda ve bir yan etkinin kasıtlı olup olmadığını söyleyememenizdir. Uyarılarla, en azından sorunun farkında olduklarını biliyorsunuz.
Robin Bennett

Ya da benim durumumda, birkaç binden fazla değer içeren bir numaralandırma üzerinde 3000'den fazla hat anahtarı ifadesi içeren gömülü bir sistemden bir dosyayı içe aktarırsınız. "Düşen" uyarılar (goto kullanarak kaçınılması gereken) bir dizi "ele alınmayan" hatayı maskeledi ... gömülü derleyici bunlardan herhangi birini yaymadı, ama yine de hatalar önemliydi.
Moz

15

Sabit olmayan uyarılar , er ya da geç, kodunuzda hatalara yol açar .


Örneğin, bir bölümleme hatasının hata ayıklanması için programlayıcının, kodunuzda genellikle bölümleme hatasına neden olan satırdan daha önce bulunan bir hatanın kökünü (nedenini) izlemesi gerekir.

Nedenin, derleyicinin yok saydığınız bir uyarı verdiği bir satır olması ve segmentasyon hatasına neden olan satır, sonunda hatayı atan satırdır.

Uyarının düzeltilmesi sorunun çözülmesine yol açar .. Klasik!

Yukarıdakilerin bir gösterimi .. Aşağıdaki kodu göz önünde bulundurun:

#include <stdio.h>

int main(void) {
  char* str = "Hello world!";
  int idx;

  // Colossal amount of code here, irrelevant to 'idx'

  printf("%c\n", str[idx]);

  return 0;
}

GCC'ye geçen "Wextra" bayrağı ile derlendiğinde:

main.c: In function 'main':
main.c:9:21: warning: 'idx' is used uninitialized in this function [-Wuninitialized]
    9 |   printf("%c\n", str[idx]);
      |                     ^

hangi ı olabilir aldırmayarak kodu çalıştırmak .. Ve benim IP Epicurus profesör dediği gibi o zaman, bir "büyük" segment hataya tanık olacaktır:

Segmentasyon hatası

Bunu gerçek dünya senaryosunda hata ayıklamak için, segmentasyon hatasına neden olan çizgiden başlayacak ve nedenin kökeninin ne olduğunu izlemeye çalışacaklar. Bu muazzam miktarın içinde ive striçinde ne olduğunu araştırmak zorunda kalacaklardı. orada kod ...

Bir güne kadar, kendileri idxbaşlatılmamış olarak kullanıldıklarını keşfettikleri durumda buldular , bu yüzden bir çöp değeri var, bu da ipin (yolun) sınırlarının ötesinde endekslenmesine neden oluyor ve bu da bir segmentasyon hatasına yol açıyor.

Sadece uyarıyı görmezden gelmeselerdi, hatayı hemen bulurlardı!


4
Başlığınıza: illa ki değil. Örneğin, gerçekten ihtiyaç duymayan bir formülde parantez kullanılmasını öneren bir uyarı, hiçbir zaman hataya neden olmayacak bir sorun olmadığını gösterir. Belirli bir programlama dilinde operatör öncelikleri değişmez. Hiç.
Marc van Leeuwen

4
@MarcvanLeeuwen Eğer alıntı örneği olabilir operatör öncelik hatırlamaz programcı doğru formül, bir az şey değiştirir örneğin, tho hata dönüşür. Uyarı size şunu söyler: "bir noktada belirsiz olabilir, daha açık hale getirmek için bazı parantezler ekleyin". Her ne kadar orijinal gönderinin başlığının her zaman doğru olmadığı konusunda hemfikir olmalıdır.
Hubert Jasieniecki

^ Her şey bir hataya dönüştürülebilir. Bir hatayı kısmen parantez içindeki koda, tam parantez içindeki koda eklemek kadar kolaydır.
Jim Balter

... Bir kenara, "Oh, " değil " den segfaulted ilk tepki olan hata ayıklayıcı için sorularım var Tamam, nerede ve tanımlanmış?` `str[idx]stridx
Justin Time - Monica

2
Bir segmentasyon hatası alırsanız şanslısınız. Daha az şanslıysanız, şans eseri idxtestinizde beklediğiniz değer olabilir (beklenen değer 0 ise pek olası değildir) ve gerçekte konuşlandırıldığında asla yazdırılmaması gereken bazı hassas verileri gösterebilir.
celtschk

14

Uyarıları hata olarak Tedavisi öz disiplin sadece ortalama şudur: testin o parlak yeni özellik için bir program derleme, ama sen olamaz sen özensiz parçalar düzeltene kadar. Sağlanan ek bilgi yoktur Werror, sadece öncelikleri çok net bir şekilde belirler:

Varolan koddaki sorunları düzeltene kadar yeni kod eklemeyin

Gerçekten önemli olan zihniyet, araçlar değil. Derleyici tanılama çıktısı bir araçtır. MISRA (gömülü C için) başka bir araçtır. Hangisini kullandığınız önemli değildir, ancak derleyici uyarıları elde edebileceğiniz en kolay araçtır (ayarlamak için sadece bir bayraktır) ve sinyal-gürültü oranı çok yüksektir. Bu yüzden kullanmamanın bir nedeni yok .

Hiçbir alet yanılmaz değildir. Yazarsanız const float pi = 3.14;, çoğu araç size π yol boyunca sorunlara yol açabilecek kötü bir hassasiyetle tanımladığınızı söylemez. Çoğu araç, if(tmp < 42)değişkenlere anlamsız adlar vermenin ve sihirli sayılar kullanmanın büyük projelerde felaketin bir yolu olduğu bilinse bile, bir kaş kaldırmaz . Sen yazdığınız herhangi bir "hızlı testi" kod sadece budur anlamak zorunda: Bir test ve siz hala kendi eksikliklerini bkz yaparken, diğer görevler geçmek hemen önce almalıyız. Bu kodları olduğu gibi bırakırsanız, iki ay geçirdikten sonra yeni özellikler eklemek hata ayıklamak çok daha zor olacaktır.

Doğru zihniyete girdikten sonra, kullanmanın bir anlamı yoktur Werror. Uyarı olarak uyarı almak, başlamak üzere olduğunuz hata ayıklama oturumunu çalıştırmanın hala mantıklı olup olmadığı konusunda bilinçli bir karar vermenizi veya iptal etmenizi ve önce uyarıları düzeltmenizi sağlayacaktır.


3
Daha iyisi veya daha kötüsü, clippyRust için linting aracı aslında sabit "3.14" hakkında uyarır. Aslında dokümanlardaki bir örnek . Ancak adından da anlaşılacağı gibi, clippyagresif bir şekilde yardımcı olmaktan gurur duyar.
emk

1
@emk Bu örnek için teşekkürler, belki de cevabımı asla "asla" demeyecek şekilde yeniden yazmalıyım . Kesin olmayan π değerlerini kontrol etmenin imkansız olduğunu söylemek istemedim, sadece uyarılardan kurtulmanın iyi kod kalitesini garanti etmediğini söylemedim.
Dmitry Grigoryev

Hataların verdiği uyarılardan biri, otomatik derlemelerin başarısız olacağı ve böylece bir şeyin yanlış gittiğini size uyaracağıdır. Otomatik yapılar da lintingi otomatikleştirmeye izin verir (patlama 3 ... 2 ... 1 .. :)
Móż

8

Eski gömülü C koduyla çalışan biri olarak, derleyici uyarılarını etkinleştirmek, düzeltmeler önerirken çok fazla zayıflık ve araştırma yapılacak alanların gösterilmesine yardımcı oldu. Gcc kullanarak -Wallve -Wextrahatta -Wshadowhayati hale gelmiştir. Her bir tehlikeye gitmeyeceğim, ancak kod sorunlarını göstermeye yardımcı olan bir kaçını listeleyeceğim.

Geride kalan değişkenler

Bu, bitmemiş çalışmalara ve sorun olabilecek tüm geçirilen değişkenleri kullanamayan alanlara kolayca işaret edebilir. Bunu tetikleyebilecek basit bir işleve bakalım:

int foo(int a, int b)
{
   int c = 0;

   if (a > 0)
   {
        return a;
   }
   return 0;
}

Bunu -Wall veya -Wextra olmadan derlemek sorun çıkarmaz. -Wall size casla kullanılmadığını söyleyecektir :

foo.c: 'foo' işlevinde:

foo.c: 9: 20: uyarı: kullanılmayan değişken 'c' [-Wunused-değişken]

-Wextra ayrıca b parametrenizin hiçbir şey yapmadığını da söyleyecektir:

foo.c: 'foo' işlevinde:

foo.c: 9: 20: uyarı: kullanılmayan değişken 'c' [-Wunused-değişken]

foo.c: 7: 20: uyarı: kullanılmayan parametre 'b' [-Wunused-parametre] int foo (int a, int b)

Global Değişken gölgeleme

Bu biraz zor ve -Wshadowkullanılana kadar görünmedi . Yukarıdaki örneği sadece eklemek için değiştirelim, ancak her ikisini de kullanmaya çalışırken çok fazla karışıklığa neden olan bir yerel ile aynı ada sahip bir küresel var.

int c = 7;

int foo(int a, int b)
{
   int c = a + b;
   return c;
}

-Wshadow açıldığında, bu sorunu tespit etmek kolaydır.

foo.c: 11: 9: uyarı: 'c' bildirimi küresel bir bildirimi gölgeliyor [-Wshadow]

foo.c: 1: 5: not: gölgeli bildirim burada

Dizeleri biçimlendirme

Bu, gcc'de fazladan bayrak gerektirmez, ancak geçmişte hala sorunların kaynağı olmuştur. Verileri yazdırmaya çalışan, ancak biçimlendirme hatası olan basit bir işlev şöyle görünebilir:

void foo(const char * str)
{
    printf("str = %d\n", str);
}

Biçimlendirme bayrağı yanlış olduğundan ve dize mutlu bir şekilde bunu istediğini söyleyemeyeceği için dizeyi yazdırmaz:

foo.c: 'foo' işlevinde:

foo.c: 10: 12: uyarı: '% d' biçimi 'int' türünde bağımsız değişken bekliyor, ancak 2 bağımsız değişkeninde 'const char *' türü var [-Wformat =]


Bunlar, derleyicinin sizin için iki kez kontrol edebileceği birçok şeyden sadece üçü. Başkasının işaret ettiği, başlatılmamış bir değişken kullanmak gibi başka pek çok şey var.


7
Gömülü dünyada, beni en çok endişelendiren uyarılar " possible loss of precision" ve " comparison between signed and unsigned" uyarılarıdır. Kaç "programcı" bunları görmezden kavramak zor buluyorum (aslında, neden hata olmadığını gerçekten emin değilim)
Mawg Monica

3
İkinci durumda, @Mawg, bunun bir hata olmamasının birincil nedeninin sonucun sizeofimzasız olması, ancak varsayılan tamsayı türünün imzalanmış olması gerektiğine inanıyorum . sizeofSonuç tipi, size_tgenel olarak tam sayılar "olarak kullanılmak üzere amaçlanan ise, tipik olarak, örneğin, hizalama veya dizi / muhafaza elemanı sayısı olarak tipi boyutu ile ilgili bir şey için kullanılır int, aksi takdirde gerekli". Birçok kişi bu şekilde kullanılması öğretilir ne kadar göz önüne alındığında intonların konteynerler (karşılaştırarak tekrarlatacak intiçin size_tkabaca her şeyi kıracak bir hata yapma). ; P
Justin Time - Monica'yı

6

Bu C için özel bir cevaptır ve bu neden C için diğer her şeyden çok daha önemlidir.

#include <stdio.h>
int main()
{
   FILE *fp = "some string";
}

Bu kod bir uyarı ile derlenir . Gezegendeki hemen hemen her dilde (engelleme montaj dili) hatalar nelerdir ve olmalıdır C'deki uyarılardır . C'deki uyarılar neredeyse her zaman kılık değiştirme hatalarıdır. Uyarılar düzeltilmeli, bastırılmamalıdır.

İle gcc, biz bunu yapıyoruz gcc -Wall -Werror.

Bu ayrıca bazı MS güvenli olmayan API uyarıları konusundaki yüksek hassasiyetin nedeniydi. Çoğu insan C programlama, uyarıları hata olarak ele almanın zor yolunu öğrendi ve bu tür şeyler aynı tür bir şey değildi ve taşınabilir olmayan düzeltmeler istedi.


5

BİLGİSAYAR UYARILARI ARKADAŞINIZ (bağırmak değil, vurgu için büyük harf).

Eski Fortran-77 sistemleri üzerinde çalışıyorum. Derleyici bana değerli şeyler anlatıyor: Eğer kullanılmayan bir değişken veya altyordam argümanı varsa, değişkene bir değer ayarlanmadan önce yerel bir değişken kullanarak, altyordam çağrısındaki argüman veri türü uyuşmazlıkları. Bunlar neredeyse her zaman hatalardır.

Uzun bir gönderiden kaçınmak: Kodum temiz bir şekilde derlendiğinde% 97 çalışıyor. Birlikte çalıştığım diğer adam, tüm uyarıları kapalı derler, hata ayıklayıcıda saatler veya günler geçirir, sonra yardım etmemi ister. Kodunu uyarılarla derliyorum ve ona ne düzeltmesi gerektiğini söylüyorum.


5

Derleyici uyarılarını her zaman etkinleştirmelisiniz, çünkü derleyici genellikle kodunuzdaki sorunun ne olduğunu söyleyebilir. Bunu yapmak -Wall -Wextraiçin derleyiciye geçersiniz .

Uyarıları genellikle hata olarak değerlendirmelisiniz, çünkü uyarılar genellikle kodunuzda bir sorun olduğunu gösterir. Ancak, bu hataları göz ardı etmek genellikle çok kolaydır. Bu nedenle, bunları hata olarak işlemek derlemenin başarısız olmasına neden olur, böylece hataları yok sayamazsınız. Uyarıları hata -Werrorolarak değerlendirmek için derleyiciye geçin.


4

C ++ 'da derleyici uyarıları bazı nedenlerden dolayı çok yararlıdır.

1 - Operasyonlarınızın nihai sonucunu etkileyebilecek bir hata nerede yapabileceğinizi göstermenize izin verir. Örneğin, bir değişkeni başlatmadıysanız veya "==" yerine "=" yazarsanız (yalnızca örnekler vardır)

2 - Kodunuzun c ++ standardına uygun olmadığını göstermenize de izin verir. Eğer kod gerçek standarda uygunsa, örneğin kodu başka bir plaka formuna taşımak kolay olacaktır.

Genel olarak, uyarılar, kodunuzda algoritmanızın sonucunu etkileyebilecek veya kullanıcı programınızı kullanacağında bazı hataları önleyebilecek hatalarınız olduğunu göstermek için çok kullanışlıdır.


4

Uyarıları göz ardı etmek, sadece gelecekte başkası için sorunlara neden olmakla kalmayacak, aynı zamanda sizin tarafınızdan daha az fark edilen önemli derleme mesajlarına neden olacak özensiz kod bıraktığınız anlamına gelir. Daha fazla derleyici çıktısı, daha az kimse fark eder veya rahatsız eder. Daha iyi temiz. Ayrıca ne yaptığınızı bildiğiniz anlamına gelir. Uyarılar çok profesyonelce, dikkatsiz ve risklidir.


4

Bir zamanlar elektronik test ekipmanı üreten büyük bir (Fortune 50) şirkette çalıştım.

Grubumun ana ürünü, yıllar içinde tam anlamıyla yüzlerce uyarı üretmek için gelen bir MFC programı idi. Hangi hemen hemen tüm durumlarda göz ardı edildi.

Bu, hatalar meydana geldiğinde soğuk bir kabus.

Bu pozisyondan sonra, yeni bir başlangıçta ilk geliştirici olarak işe alınacak kadar şanslıydım.

Derleyici uyarı seviyeleri oldukça gürültülü olacak şekilde tüm yapılarda 'uyarı yok' politikasını teşvik ettim.

Uygulamamız, her durumda, geliştiricinin gerçekten iyi olduğundan emin olan kod için #pragma uyarısı - push / devre dışı / pop kullanmaktı, her halükarda hata ayıklama düzeyinde bir günlük ifadesi kullanmaktı.

Bu uygulama bizim için iyi çalıştı.


1
Destekliyorum. #pragma warningsadece uyarıları bastırmakla kalmaz, diğer programcılara bir şeyin kasıtlı ve tesadüfi olmadığını hızlı bir şekilde iletmenin ikili amaçlarına hizmet eder ve bir şey kırıldığında potansiyel olarak sorunlu alanları hızlı bir şekilde bulmak, ancak hataları / uyarıları düzeltmek için bir arama etiketi görevi görmez. düzelt.
Justin Time - Monica'yı

Haklısın Justin, tam olarak böyle görüyorum #pragma uyarısı
Jim In Texas

3

Uyarı, gerçekleşmeyi bekleyen bir hatadır. Bu nedenle, derleyici uyarılarını etkinleştirmeli ve tüm uyarıları kaldırmak için kodunuzu düzenlemelisiniz.


3

Sadece var bir hata olarak uyarılar tedavi ile sorun: Başka kaynaklardan gelen kodu kullanarak olduğunuzda (örneğin, mikro $ ** t kütüphaneler, açık kaynak projeleri), onlar kendi işini doğru yapmak ve onların kod derleme üretir vermedi ton uyarılar.

Ben her zaman herhangi bir uyarı veya hata oluşturmaz kodumu yazmak ve herhangi bir yabancı gürültü üretmeden derleyene kadar temizlemek. Çalışmak zorunda olduğum çöp beni korkutuyor ve büyük bir proje inşa edip derlemenin yalnızca hangi dosyaları işlediğini duyurması gereken yere kadar bir uyarı akışı izlediğimde şaşırdım.

Kodumu da belgeliyorum çünkü yazılımın gerçek ömür boyu maliyetinin çoğunlukla bakımdan geldiğini biliyorum, başlangıçta yazmaktan değil, ama bu farklı bir hikaye ...


Vurmayın, derleyici uyarılarını müşterilere yüksek sesle okuyabilen insanlar için danışmanlık işinde iyi para var.
Moz

Uyarıları üreten diğer kaynaklardan Kod değil gerekli yazarlar özensiz olduklarını ortalama. Ayrıca, kodu farklı bir uyarı kümesi oluşturan farklı bir derleyici ile derledikleri anlamına da gelebilir. Kod, bir derleyici üzerinde uyarı yapmadan derlenebilir ve diğerinde uyarı oluşturabilir. Ya da belki de sadece farklı bir uyarı seçenekleri kümesi; örneğin kullandılar -Wallve siz kullanın -Wall -Wextra.
celtschk

2

Bazı uyarılar, kodda olası anlamsal hata veya olası UB anlamına gelebilir. Örneğin ;sonra if()kullanılmayan değişken, genel değişken yerel tarafından maskeli veya imzalı ve imzasız karşılaştırılması. Birçok uyarı derleyicideki statik kod analizörü veya derleme zamanında tespit edilebilen ISO standardının ihlali ile ilgilidir. Bu olaylar belirli bir durumda yasal olsa da, çoğu zaman tasarım sorunlarının bir sonucu olacaktır.

Bazı derleyiciler, örneğin gcc, "hata olarak uyarılar" modunu etkinleştirmek için bir komut satırı seçeneğine sahiptir, acemi kodlayıcıları eğitmek için acımasız bir araç.


1

C ++ derleyicileri tanımsız davranış açıkça sonuçları bu kodu derleme kabul edin gerçeği hiç derleyici önemli bir kusurdur. Bunu düzeltmemelerinin nedeni, muhtemelen bunu yapmanın bazı kullanılabilir yapıları bozmasıdır.

Uyarıların çoğu, yapının tamamlanmasını engelleyen ölümcül hatalar olmalıdır. Varsayılan olarak sadece hataları görüntüleme ve derleme işlemini yapma varsayılanları yanlıştır ve uyarıları hata olarak değerlendirmek ve bazı uyarılar bırakmak için bunları geçersiz kılmazsanız, programınızın çökmesine ve rastgele şeyler yapmasına neden olursunuz.


İronik olarak, bir çok tanımlanmamış davranış aslında uyarılara neden olmaz, ancak sessizce kötü bir küçük zaman bombasına sessizce derler. ; P
Justin Time - Monica

1
Sorun, standart bir hata mesajı talep ederse, sorunun oluştuğu tüm durumlarda bu hata mesajının verilmesi gerektiğidir , ancak asla sorun ortaya çıkmazsa. Ancak tanımlanmamış davranış gibi durumlarda karar vermek imkansız olabilir. Örneğin, aşağıdaki kodu göz önünde bulundurun: int i; if (fun1()) i=2; if (fun2()) i=3; char s="abcde"[i];Bu kod, yalnızca fun1()ve her ikisi de aynı işlev yürütmesinde fun2()dönebiliyorsa tanımsız davranış gösterir false. Hangisi doğru olabilir veya olmayabilir, ancak derleyici nasıl söyler?
celtschk

-2

Bazı derleyiciler aşağıdakiler de dahil olmak üzere bazı yaygın programlama hatalarını bildirmede kötü olduğundan derleyici uyarılarını kesinlikle etkinleştirmelisiniz: -

-> bir değişkenin başlangıcı unutulur -> bir işlevden bir değer döndürülür kaçırılır -> printf ve scanf ailelerindeki bir işlevin önceden bildirilmeden kullanılan biçim dizesiyle eşleşmeyen basit argümanlar, yalnızca c

Bu nedenle, bu işlevler algılanıp rapor edilebildiğinden, genellikle varsayılan olarak değil; bu nedenle derleyici seçenekleriyle bu özellik açıkça istenmelidir.


-32

Sakin ol: gerek yok, gerekli değil. -Wall ve -Werror, kodları yeniden düzenleyen manyaklar tarafından kendileri için tasarlandı: kullanıcı tarafında derleyici güncellemelerinden sonra mevcut yapıları kırmamak için derleyici geliştiricileri tarafından icat edildi . Özellik hiçbir şey değildir, ama her şey yapıyı kırma veya kırmama kararı ile ilgilidir.

Kullanmak ya da kullanmak tamamen tercihinize bağlıdır. Her zaman kullanıyorum çünkü hatalarımı düzeltmeme yardımcı oluyor.


19
Zorunlu olmasa da , bunların kullanılması şiddetle tavsiye edilir
Spikatrix

18
-Wall and -Werror was designed by code-refactoring maniacs for themselves.[alıntı gerekli]
YSC

22
Görünüşe göre kendinle çelişiyorsun. Eğer her zaman "hatalarınızı düzeltmeye yardımcı olduğu için kullanırsanız", yeni programcılara öğretmeye değmez, böylece her yerden başlayarak bunu yaparlar mı? Bu sorunun, derlemeden derlemenin mümkün olup olmadığını sorduğunu düşünmüyorum -Wallve -Werrorsadece bunun iyi bir fikir olup olmadığını soruyor. Son cümlenizden söylediğiniz gibi geliyor.
scohe001

12
Yazmadığınız kodun korunması konusunda daha fazla deneyim kazandığınızda, bu yanıtı tekrar ziyaret edin.
Thorbjørn Ravn Andersen

Bu yararlı bir cevap değil. OP sorusunda 4 soru işareti vardır. Bu cevap kaç cevap veriyor?
Anders
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.