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?
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:
C ve C ++ derleyicileri, bazı yaygın programcı hatalarını varsayılan olarak bildirirken kötü bir şekilde kötüdür :
return
bir fonksiyondan bir değeri unutmakprintf
ve scanf
ailelerBunlar saptanabilir ve rapor edilebilir, sadece varsayılan olarak değil; bu özellik derleyici seçenekleriyle açıkça istenmelidir.
Bu derleyicinize bağlıdır.
Microsoft C ve C ++ derleyicileri anahtarları gibi anlıyorum /W1
, /W2
, /W3
, /W4
ve /Wall
. En azından kullanın /W3
. /W4
ve /Wall
sistem 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
, -Wpedantic
ve 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.
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 -Werror
yayı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.
Bu yine derleyici anahtarları ile yapılır. /WX
Microsoft içindir, diğerlerinin çoğu kullanır -Werror
. Her iki durumda da, üretilen uyarılar varsa derleme başarısız olur.
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 b
için a
ve 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.
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 ..."
if (returnCodeFromFoo = foo(bar))
, kodu tek bir yerde yakalamak ve test etmek için yazabilir ve anlamına gelebilir ( Tek amacının foo
yan etkilere sahip olduğunu varsayın !) Gerçekten çok deneyimli bir programcının bunun bir iyi kodlama tarzı noktanın yanındadır;)
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).
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.
equals
/ hashCode
) ve bunlardan hangisinin bildirildiği bir uygulama kalitesi sorunudur.
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.
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.
Ö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 i
ve str
içinde ne olduğunu araştırmak zorunda kalacaklardı. orada kod ...
Bir güne kadar, kendileri idx
baş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ı!
str[idx]
str
idx
idx
testinizde 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.
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.
clippy
Rust 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, clippy
agresif bir şekilde yardımcı olmaktan gurur duyar.
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 -Wall
ve -Wextra
hatta -Wshadow
hayati hale gelmiştir. Her bir tehlikeye gitmeyeceğim, ancak kod sorunlarını göstermeye yardımcı olan bir kaçını listeleyeceğim.
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 c
asla 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)
Bu biraz zor ve -Wshadow
kullanı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
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.
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)
sizeof
imzasız olması, ancak varsayılan tamsayı türünün imzalanmış olması gerektiğine inanıyorum . sizeof
Sonuç tipi, size_t
genel 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 int
onların konteynerler (karşılaştırarak tekrarlatacak int
için size_t
kabaca her şeyi kıracak bir hata yapma). ; P
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.
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.
Derleyici uyarılarını her zaman etkinleştirmelisiniz, çünkü derleyici genellikle kodunuzdaki sorunun ne olduğunu söyleyebilir. Bunu yapmak -Wall -Wextra
iç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 -Werror
olarak değerlendirmek için derleyiciye geçin.
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.
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.
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ı.
#pragma warning
sadece 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.
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 ...
-Wall
ve siz kullanın -Wall -Wextra
.
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ç.
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.
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?
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.
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.
-Wall and -Werror was designed by code-refactoring maniacs for themselves.
[alıntı gerekli]
-Wall
ve -Werror
sadece bunun iyi bir fikir olup olmadığını soruyor. Son cümlenizden söylediğiniz gibi geliyor.