Soru Derleyici neden boş bir if ifadesi hakkında uyarmadı?


Keil uVision v4.74 kullanıyorum ve "Tüm Uyarılar" seçeneğini etkinleştirdim.

Ben yazdım kasıtlı kod:

if(condition matched)
{
 //do something
}

Projemi yeniden oluşturduğumda 0 hata, 0 uyarısı aldım.

Ancak, ben kazara yazdı:

if(condition matched);
{
 //do something
}

Ayrıca 0 hata, 0 uyarı var.

Bunu bulmak benim için imkansızdı. ; koşulu takip eden problemin köküdür.

Derleyici neden bir uyarı gibi davranmadı ve bana bilgi verdi?


25
2018-05-27 11:56


Menşei


Neden o? Bu çok iyi oluşturulmuş ve yasal bir ifadedir. Burada hiçbir şey uyarılamaz. - ckruczek
Bir değişkeni bildirdiğimde ve onu kullanmadığımda, "değişken bildirildi, ancak tanımlanmamış" diyor. "İfadesi kullanmış ama ifşa için vücut yok mu?" Gibi bir şey söylemeli mi? - Akshay Immanuel D
Burada bahsetmek istediğim bir şey var. Bu tamamen ilgili değil keil.. genel programlamada da olacak. - someone
Derleyici bir ve bir uyarı vermelidir, “c kullanıyorsunuz, güvenlik ağı beklemiyorsunuz”. - Ian Ringrose
@ckruczek Ama ... tam olarak bu uyarıların ne için olduğunu. İyi oluşmamış ve yasal değilse, bu bir hata olur. Uyarılar yasal olan ancak mantık hataları gibi şüpheli olan şeyler içindir. - GrandOpener


Cevaplar:


Bu bir hata değil çünkü boş bir deyim olduğu geçerli bir ifade; Ancak, şüpheli kod olduğundan, derleyici uyarısı için mükemmel bir adaydır - ve aslında gcc -Wall -Wextra bu konuda uyarıyor:

int foo(int x) {
  if(x); {
    return 42;
  }
  return 64;
}

/tmp/gcc-explorer-compiler116427-37-l1vpg4/example.cpp: In function 'int foo(int)':
2 : warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
if(x); {
^

https://godbolt.org/g/RG1o7t

her ikisi de clang ve VC ++ da bunu yap.

gcc 6 bile daha akıllıdır (belki de çok fazla) ve bir şeylerin yanlış olduğuna dair bir ipucu olarak girintiyi bile alır:

/tmp/gcc-explorer-compiler116427-76-1sfy0y/example.cpp: In function 'int foo(int)':
2 : warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
if(x); {
^
2 : warning: this 'if' clause does not guard... [-Wmisleading-indentation]
if(x); {
^~
2 : note: ...this statement, but the latter is misleadingly indented as if it is guarded by the 'if'
if(x); {
^

Yani, ya uyarıların yeterince uzaması ya da derleyiciniz yeterince akıllı değildir.

Daha yararlı bir derleyiciye geçiş yapma olasılığınız yoksa, statik analiz araçlarını kullanmayı düşünün; örneğin, bu durumda cppcheck hatası verir (verildiğinde --enable=all --inconclusive bayraklar):

[mitalia@mitalia ~/scratch]$ cppcheck --enable=all --inconclusive emptyif.c 
Checking emptyif.c...
[emptyif.c:2]: (warning, inconclusive) Suspicious use of ; at the end of 'if' statement.
[emptyif.c:1]: (style) The function 'foo' is never used.

Ek - çeşitli derleyiciler için ilgili uyarılar (güncelleştirmek için çekinmeyin)

Özetlemek için ilgili uyarı seçenekleri:

  • gcc  -Wempty-body; dahil -Wextra;
  • gcc> = 6.0, ayrıca -Wmisleading-indentation yardım edebilir; dahil -Wall;
  • çınlama  -Wempty-body; dahil -Wextra çok;
  • Visual C ++  C4390, dahil /W3

Statik analiz araçları:

  • cppcheck  --enable=warning --inconclusive; dahil --enable=all --inconclusive

51
2018-05-27 12:06



Keil'i "Tüm Uyarılar" ın ötesinde ne kadar daha fazla kovalayabilirsin? - Akshay Immanuel D
@ Vector9: armcc tarafından desteklenen uyarıların listesine hızlıca bakıldığında, bu konuyla ilgili hiçbir şey görünmemektedir. Ancak ben onu görüyorum. destekliyor kullanma gccBu yüzden bir deneme (belki de üretimde değil, ancak zaman zaman farklı bir derleyici tanılama kümesine bakmak için) verebilirsiniz. Ama yine de, ben Keil / armgcc uzmanı değilim, bu yüzden çoğunlukla bir ikame değiştirme olarak veya derleyiciler arasında geçiş yapmak için bir kabus olacaksa kullanılıp kullanılamayacağını bilmiyorum. - Matteo Italia
Evet, MSVC uyardı: warning C4390: ';': empty controlled statement found; is this the intent?. Aslında bir seviye 3 uyarısıYani, hatta W4'e ihtiyacınız yok. Varsayılan uyarı seviyesi bunu yakalayacaktır. - Cody Gray♦
@mucaho: -Wextra hatta clang içinde içerir; Bu uyarıya özel bayrak, aynı gccyani -Wempty-body. - Matteo Italia
@davenpcj Bir linterin kullanılmasını önermek bir cevap olarak göndermeye değer olabilir, çünkü (muhtemelen) derleyicileri değiştirmeyi gerektirmez. - jpmc26


Matteo'nun cevabı belirtildiği gibi, kod kesinlikle geçerlidir. Bu şekilde yorumlanıyor:

if(condition)
    ;  // do nothing

// unrelated block
{
    // do something
}

Bu biraz teknik bir meseledir, ancak boş gövdeli koşulların bazı çok güzel kullanımları vardır.

Lint ve diğer bu tür kod akıl yürütme araçları, girintideki beklenmedik değişiklik hakkında uyarıda bulunacak ve teknik olarak derleyici hataları olmasa da stilistik olabilecek ek hatalar yakalayacaktır.

Ya da güvenlik sorunları, değişken renklendirme, arabellek yönetimi, kötü dökümler gibi olası bakım sorunları, vb. "Derleyici hataları" kategorisine girmeyen çok fazla kod sorunu var.

@ Jpmc26'nin belirttiği gibi, bu yaklaşım, kullanmak için derleyicileri değiştirmenize gerek olmadığından daha iyi olabilir. Yine de, bağımsız olarak ikiyi yönetme yeteneğini de kişisel olarak buluyorum.


2
2018-05-31 16:31