Bağlam olarak, Google’da çalışan bir Clang geliştiricisiyim. Google’da, Clang’ın teşhis yöntemlerini (esas olarak) tüm C ++ geliştiricilerimize sunduk ve Clang’ın uyarılarını hata olarak da değerlendirdik. Hem bir Clang geliştiricisi hem de Clang'ın teşhis alanlarından daha büyük kullanıcılarından biri olarak, bu bayraklara ve bunların nasıl kullanılabileceğine ışık tutmaya çalışacağım. Açıkladığım her şeyin genel olarak Clang'a uygulanabilir olduğunu ve C, C ++ veya Objective-C'ye özgü olmadığını unutmayın.
TL; DR Sürümü: Lütfen geliştirdiğiniz kodlarda -Wall
ve -Werror
en azından kullanın . Biz (derleyici geliştiricileri) buraya iyi sebeplerden dolayı uyarılar ekliyoruz: hata buluyorlar. Sizin için hata yakalayan bir uyarı bulursanız, onu da açın. -Wextra
Burada bir sürü iyi aday deneyin . Bunlardan biri karlı kullanmanız için çok gürültülü ise, bir hata bildiriniz . Eğer "bariz" bir hata içeren bir kod yazarsanız fakat derleyici bunun hakkında uyarmadıysa, bir hata yazınız.
Şimdi uzun versiyon için. Öncelikle uyarı bayrağı gruplamaları hakkında biraz bilgi edinin. Clang'da (ve GCC'de sınırlı bir ölçüde) bir çok "gruplandırma" uyarısı vardır. Bu tartışma ile ilgili bazıları:
- Varsayılan olarak: Açıkça devre dışı bırakmadığınız sürece bu uyarılar her zaman açıktır.
-Wall
: Bunlar, geliştiricilerin hem değerlerine güvenlerinin yüksek , hem de yanlış pozitif oranın düşük olduğu uyarılarıdır .
-Wextra
: Bunlar değerli ve sağlam olduğuna inanılan uyarılardır (yani, adamcağınız bir araba değildir), ancak yanlış pozitif oranlara veya ortak felsefi itirazlara sahip olabilirler.
-Weverything
: Bu,
Clang'da her uyarıyı tam anlamıyla sağlayan deli bir grup . Bunu kodunda kullanma. Kesinlikle Clang geliştiricileri veya hangi uyarıların mevcut olduğunu araştırmak için tasarlanmıştır .
Yukarıda belirtilen uyarıların Clang'da nereye gittiğini belirleyen iki ana kriter vardır ve bunların ne anlama geldiğini netleştirelim. Birincisi , uyarının belirli bir oluşumunun potansiyel
değeridir . Uyarı tetiklendiğinde ve
kodla ilgili bir sorunu doğru şekilde tanımladığında , kullanıcıya (geliştirici) beklenen fayda budur .
İkinci kriter yanlış-pozitif raporlar fikridir . Bunlar, uyarının kodun üzerine ateşlendiği durumlardır, ancak belirtilen potansiyel problem aslında programın kapsamı veya başka bir kısıtlaması nedeniyle gerçekleşmez. Uyarılan kod aslında doğru davranıyor. Bunlar, özellikle uyarı bu kod paternine ateş etmek niyetinde olmadığında kötüdür. Bunun yerine, uyarının uygulanmasında orada ateşlenmesine neden olan bir eksikliktir.
Clang uyarıları için, değerin stil, tat veya kodlama kuralları açısından değil , doğruluk açısından olması gerekir . Bu {}
, bir if
ifadenin gövdesinde kullanılmadığı zaman uyarılması gibi istenen uyarıları engellemek için mevcut uyarı kümesini sınırlar . Clang ayrıca yanlış pozitiflere karşı çok hoşgörüsüzdür . Diğer birçok derleyiciden farklı olarak, yapının tam olarak yazılması, fazladan '()', heceler ve hatta önişlemci makrolarının varlığı veya yokluğu dahil olmak üzere yanlış pozitifleri budamak için inanılmaz çeşitli bilgi kaynakları kullanacaktır!
Şimdi Clang'dan bazı gerçek dünya örnekleri uyarları alalım ve nasıl kategorize edildiklerine bakalım. İlk önce, varsayılan bir uyarı:
% nl x.cc
1 class C { const int x; };
% clang -fsyntax-only x.cc
x.cc:1:7: warning: class 'C' does not declare any constructor to initialize its non-modifiable members
class C { const int x; };
^
x.cc:1:21: note: const member 'x' will never be initialized
class C { const int x; };
^
1 warning generated.
İşte bu uyarıyı almak için bayrak gerekmedi. Bunun sebebi, kodun hiçbir zaman doğru olmadığı, uyarıya yüksek değer veren ve uyarı yalnızca Clang'ın bu kovaya düştüğünü ispatladığı kodun üzerine, sıfır -yanlış-pozitif bir oran vermesidir.
% nl x2.cc
1 int f(int x_) {
2 int x = x;
3 return x;
4 }
% clang -fsyntax-only -Wall x2.cc
x2.cc:2:11: warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized]
int x = x;
~ ^
1 warning generated.
Clang -Wall
bu uyarının bayrağını gerektirir . Bunun nedeni, kasıtlı olarak başlatılmamış bir değer üretmek üzere uyardığımız kod desenini kullanan (iyi veya hasta için) önemsiz miktarda kodun mevcut olmasıdır . Felsefi olarak, bunun üzerinde bir nokta görmüyorum, ancak çoğu diğerleri aynı fikirde değil ve bu farklılığın gerçeği -Wall
bayrak altındaki uyarıyı
tetikliyor. Hala çok yüksek bir değere ve çok düşük bir
yanlış-pozitif orana sahip, ancak bazı kod tabanlarında başlangıç niteliğinde değil.
% nl x3.cc
1 void g(int x);
2 void f(int arr[], unsigned int size) {
3 for (int i = 0; i < size; ++i)
4 g(arr[i]);
5 }
% clang -fsyntax-only -Wextra x3.cc
x3.cc:3:21: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
for (int i = 0; i < size; ++i)
~ ^ ~~~~
1 warning generated.
Bu uyarı -Wextra
bayrak gerektirir . Bunun nedeni,
karşılaştırmalardaki yanlış eşleşme işaretinin aşırı yaygın olduğu çok büyük kod tabanları olmasıdır. Bu uyarı bazı hataları bulsa da, kullanıcı yazdığında kodun bir hata olma olasılığı ortalama olarak oldukça düşüktür. Sonuç, son derece yüksek bir yanlış-pozitif orandır. Ancak, tuhaf promosyon kuralları nedeniyle bir programda bir hata olduğunda, genellikle bir böceğin işaretlerini göreceli olarak yüksek bir değere sahip olduğu zaman bu uyarıyı yapmak çok zekicedir
. Sonuç olarak, Clang bunu sağlar ve bir bayrak altında gösterir.
Genellikle, uyarılar -Wextra
bayrağın dışında uzun süre yaşamaz . Clang, düzenli kullanım ve test görmeyen uyarıların uygulanmaması için çok çalışıyor. Ekteki uyarılar -Weverything
, genellikle aktif gelişimdeki veya aktif hata içeren uyarılardır. Ya sabitlenmiş ve uygun bayrakların altına yerleştirilecekler, ya da kaldırılmaları gerekiyor.
Şimdi bu şeylerin Clang'la nasıl çalıştığını anladığımıza göre, asıl soruya dönelim: Gelişiminiz için hangi uyarıları açmalısınız? Cevap maalesef buna bağlı. Durumunuz için hangi uyarıların en iyi şekilde çalıştığını belirlemek için aşağıdaki soruları göz önünde bulundurun.
- Tüm kodlarınız üzerinde kontrolünüz var mı, yoksa bazıları harici mi?
- Hedeflerin ne? Hata yakalamak veya daha iyi kod yazmak?
- Yanlış pozitif toleransınız nedir? Uyarıları susturmak için düzenli olarak ekstra kod yazmak ister misiniz?
Öncelikle ve en önemlisi, eğer kodu kontrol etmezseniz, orada fazladan uyarı vermeyi denemeyin. Bazı kapatmak için hazır olun. Dünyada birçok kötü kod var ve hepsini düzeltemeyebilirsiniz. Sorun değil. Kod üzerinde çaba için bir yol bulmak için çalışın sen kontrol eder.
Ardından, uyarılarınızdan ne istediğinizi anlayın. Bu farklı insanlar için farklı. Clang, korkunç hatalar veya uzun zaman önceliğine sahip olduğumuz kod kalıpları üzerinde hata oranının aşırı yüksek olduğunu belirten herhangi bir seçenek olmadan uyarmaya çalışacaktır. Etkinleştirerek -Wall
, Clang geliştiricilerin C ++ kodunda gözlemlediği en yaygın hataları yakalamayı hedefleyen çok daha agresif bir dizi uyarı alacaksınız. Ancak bunların her ikisinde de
yanlış pozitif oran oldukça düşük kalmalıdır.
Son olarak, her dönüşde * yanlış-pozitif * s'leri susturmaya tamamen istekli iseniz , devam edin -Wextra
. Çok fazla gerçek böcek yakalayan, ama aptal veya anlamsız yanlış pozitif olan uyarılar fark ederseniz, hataları dosyalayın. Biz sürekli daha böcek bulma mantığı daha getirmek içinde sunmak için yollar bulmaya çalışıyoruz -Wextra
içine -Wall
biz yanlış pozitifler önlemek nerede.
Pek çok kişi bu seçeneklerin hiçbirinin onlar için doğru olmadığını görecektir. Google’da, -Wall
uyarıyı ihlal eden birçok kod nedeniyle bazı uyarıları kapattık. Bazı uyarıları, henüz etkinleştirilmemiş olmalarına rağmen -Wall
, bizim için özellikle yüksek bir değere sahip olduklarından açıkça açıkça belirttik . Kilometreniz değişecek, ancak muhtemelen benzer şekillerde de değişecek. Hepsi yerine birkaç önemli uyarının yapılması genellikle daha iyi olabilir
-Wextra
.
Herkesi-Wall
eski olmayan bir kod için açmaya teşvik ediyorum . Yeni kod için, buradaki uyarılar neredeyse her zaman değerlidir ve gerçekten kod geliştirme deneyimini daha iyi hale getirir. Tersine, ben herkese tavsiye ederim
değil ötesinde bayrakları etkinleştirmek -Wextra
. Eğer bir Clang uyarısı bulursanız -Wextra
içermez ancak kanıtlıyor ki hiç değerli senin için, basitçe bir hata dosyası ve biz muhtemelen altına koymak -Wextra
. Uyarıların bazı alt kümelerini açıkça etkinleştirip etkinleştirmemeniz, -Wextra
büyük ölçüde kodunuza, kodlama stilinize ve bu listeyi korumanın her şeyi çözmekten daha kolay olup olmayacağına bağlıdır -Wextra
.
(Her ikisi de dahil uyarıların OP'ın listesinin -Wall
ve -Wextra
yalnızca aşağıdaki uyarılar vardır) değil , bu iki grup kapsamındaki (veya varsayılan olarak açıktır). İlk grup, açık uyarı bayraklarına aşırı güvenmenin neden kötü olabileceğini vurgulamaktadır: Bunlardan hiçbiri Clang'da bile uygulanmamaktadır ! Yalnızca GCC uyumluluğu için komut satırında kabul edilirler.
-Wbad-function-cast
-Wdeclaration-after-statement
-Wmissing-format-attribute
-Wmissing-noreturn
-Wnested-externs
-Wnewline-eof
-Wold-style-definition
-Wredundant-decls
-Wsequence-point
-Wstrict-prototypes
-Wswitch-default
Orijinal listedeki gereksiz uyarıların bir sonraki kovası, bu listedeki diğerleriyle gereksiz olanlardır:
-Wformat-nonliteral
-- Alt kümesi -Wformat=2
-Wshorten-64-to-32
-- Alt kümesi -Wconversion
-Wsign-conversion
-- Alt kümesi -Wconversion
Daha kategorik olarak farklı olan bir dizi uyarı da mevcut. Bunlar, buggy ya da buggy olmayan kodlardan ziyade dil lehçesi değişkenleriyle ilgilidir. Bunun haricinde -Wwrite-strings
, bunlar Clang tarafından sağlanan dil eklentileri için uyarılardır. Clang'ın kullanımı hakkında uyarılıp uyarılmadığı, uzantının yaygınlığına bağlıdır. Clang, GCC uyumluluğunu hedeflemektedir ve bu nedenle çoğu durumda, kullanımda olan örtük dil uzantılarıyla bunu kolaylaştırmaktadır. -Wwrite-strings
OP'de yorumlandığı gibi, GCC'den program anlamını değiştiren bir uyumluluk bayrağıdır. Bu bayrağa çok pişmanım ama şu an sahip olduğu miras nedeniyle onu desteklemek zorundayız.
-Wfour-char-constants
-Wpointer-arith
-Wwrite-strings
Aslında potansiyel olarak ilginç uyarıları mümkün kılan diğer seçenekler şunlardır:
-Wcast-align
-Wconversion
-Wfloat-equal
-Wformat=2
-Wimplicit-atomic-properties
-Wmissing-declarations
-Wmissing-prototypes
-Woverlength-strings
-Wshadow
-Wstrict-selector-match
-Wundeclared-selector
-Wunreachable-code
Bunların olmama nedeni -Wall
ya -Wextra
da her zaman net değil. Bunların pek çoğu için, aslında GCC uyarıları (dayalıdır -Wconversion
,
-Wshadow
vs.) ve bu tür Clang GCC davranışını taklit etmeye çalışır olarak. Bunlardan bazılarını yavaş yavaş daha ince taneli ve kullanışlı uyarılara bölüyoruz. Bunlar daha sonra, üst düzey uyarı gruplarından birine girme olasılıkları daha yüksektir. Bu bir uyarı üzerine, almaya, söz konusu -Wconversion
olan bu yüzden büyük olasılıkla yakın gelecekte kendi "üst düzey" kategorisi kalacağını geniş. GCC'nin sahip olduğu ancak değeri düşük ve değeri yüksek yanlış pozitif oranlara sahip diğer bazı uyarılar da benzer bir kimseye ait olmayan topraklara devredilebilir.
Bunların daha büyük kovalardan birinde bulunmamasının diğer nedenleri arasında basit hatalar, çok önemli yanlış pozitif sorunlar ve geliştirme uyarıları yer alıyor. Tanımlayabildiğimler için dosyalama hataları arayacağım. Sonunda hepsi uygun bir büyük kova işaretine geçmeli veya Clang'dan çıkarılmalıdır.
Umarım bu, Clang ile uyarı durumunu netleştirir ve kullanımı veya şirketlerinin kullanımı için bir dizi uyarı almaya çalışanlar için bazı bilgiler sunar.