2016-04-01 13 views
2

Bir [[noreturn]] özniteliğiyle, bir tanıtıcıyı kullanmaya çalışıyorum ve kullanıyorum ([[noreturn]] bir C++11 standard attribute ve __attribute__((noreturn)) bir GCC/Clang uzantısıdır) ile biraz oynuyorum. Bunun bir parçası olarak, Clang -Webest-noreturn uyarısını etkinleştirdim.Şüpheli durumda ikaz uyarısı: 'foo' işlevi 'noreturn' özelliğiyle bildirilebilir mi?

> clang++ -v 
Ubuntu clang version 3.7.1-svn253742-1~exp1 (branches/release_37) (based on LLVM 3.7.1) 
Target: x86_64-pc-linux-gnu 
Thread model: posix 

foo.cpp:

enum bar 
{ 
    A = 1, 
    B, 
    C 
}; 

void foo() 
{ 
    switch (bar()) 
    { 
    case A: 
    case B: 
    case C: 
    default: 
     break; 
    } 
} 

int main() 
{ 
    foo(); 
    return 0; 
} 

Sonra derlemek:

> clang++ foo.cpp -o foo -Wmissing-noreturn -std=c++14 
foo.cpp:9:1: warning: function 'foo' could be declared with attribute 'noreturn' 
     [-Wmissing-noreturn] 
{ 
^ 
1 warning generated. 

O iade edeceğini bana görünür! Burada neler oluyor? Bu bir derleyici hatası mı?

"= 1" öğesini A'dan kaldırırsanız, uyarı vermeden düzgün şekilde derler.

foo() işlevini [[noreturn]] void foo() yaparsam, bölümleme hatasıyla çakılır.

+2

Bana bir clang böcek gibi görünüyor. –

+0

Apple (XCode) 'clang ++' (sürüm bilgisi 'Apple LLVM sürüm 7.3.0 (clang-703.0.29)' 'Hedef: x86_64-apple-darwin15.4.0' ' Konu modeli: posix' ile çoğaltabilirim . Henüz yorumlayabildiğime emin değilim - bir 'enum' için varsayılan kurucu ne yapar? (Kodunuzla bağlantı kurarak, bar() 'nın 0 döndürdüğü anlaşılır. Bu da ilginçtir. Ancak işlevin geri dönmediği anlamına gelmez.) –

+0

@JonathanLeffler - iyi soru. Eğer "A = 0" yaparsam, uyarısı yok. Daha önce de aynı davranan bir enum sınıfıyla oynuyordum. Belki de varsayılan olarak varsayılan olarak 0'a sıfırlar, bu geçersizdir ve varsayılana düşmek yerine bir tuzağa dönüşür. Ya da tanımlanmamış davranış? –

cevap

-1

Son yanıtı silmek için üzgünüz. Bu yanlıştı. Tamam noreturn, fonksiyonun asla bitmediği anlamına gelir. ve segmentasyon çünkü bar bir değişken değil

+0

"Noreturn" özniteliği (ancak süslüdür), bu işlev çağrıldığında, denetim akışının hiçbir zaman işlevden geri dönmeyeceği anlamına gelir. Bu, normalde, 'exit()' veya '_exit()' gibi bir işlevi veya programı durduran benzer bir işlevi çağırdığı anlamına gelir. Örnek kodda, 'foo()' içinden çağrılan tek işlev 'bar()' dır - ve bu enum bar {…}; 'türü için varsayılan bir kurucudur. Bunun niçin geri dönmeyeceği hemen belli olmaz - ve eğer yaparsa, o zaman foo() işlevi geri dönecektir, yani "noreturn" özelliği uygunsuz olacaktır. –

İlgili konular