2016-04-01 10 views
2

Ich habe ein bisschen mit dem [[Noreturn]] - Attribut gespielt, das ich versuche, ein Griff zu bekommen und zu nutzen (ich verstehe [[noreturn]] ist ein C++11 standard attribute und __attribute__((noreturn)) ist eine GCC/Clang-Erweiterung). Als Teil davon aktivierte ich die Clang-Warnung -Wissende-Rückkehr.Clangwarnung in zweifelhaftem Fall: Funktion 'foo' könnte mit Attribut 'noreturn' deklariert werden?

> 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; 
} 

Dann kompilieren:

> 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. 

Es scheint mir, dass es zurückkommen würde! Was ist denn hier los? Ist das ein Compilerfehler?

Wenn Sie das "= 1" aus A entfernen, wird es ohne Warnung kompiliert.

Wenn ich die foo() -Funktion [[noreturn]] void foo() mache, stürzt es mit einem Segmentierungsfehler ab.

+2

Sieht aus wie ein Clang Bug für mich. –

+0

Ich kann mit Apple (XCode) 'clang ++' reproduzieren (Versionsinfo 'Apple LLVM Version 7.3.0 (clang-703.0.29)' 'Ziel: x86_64-apple-darwin15.4.0' ' Gewindemodell: posix') . Ich bin mir nicht sicher, ob ich das noch interpretieren kann - was bringt der Standardkonstruktor für eine 'enum'? (Dinking mit Ihrem Code, es scheint, dass 'bar()' gibt 0 zurück - was interessant ist. Aber das bedeutet nicht, dass die Funktion nicht zurückkehrt.) –

+0

@ JonathanLeffler - gute Frage. Wenn ich es "A = 0" mache, hat es keine Warnung. Ich habe vorher mit einer Enum-Klasse herumgespielt, die sich genauso verhält. Vielleicht initialisiert es es immer standardmäßig auf 0, was ungültig ist, und wird zu einem Trap, anstatt auf den Standardwert zu wechseln? Oder undefiniertes Verhalten? –

Antwort

-1

Ok Entschuldigung für das Löschen der letzten Antwort. Es war falsch. Ok noreturn bedeutet, dass die Funktion niemals endet. und die Segmentierung Fould ist, weil bar ist keine Variable

+0

Das Attribut 'noreturn' (wie auch immer es dekoriert ist) bedeutet, dass beim Aufruf dieser Funktion der Steuerungsfluss niemals von der Funktion zurückkehrt. Das bedeutet normalerweise, dass es wiederum eine Funktion wie 'exit()' oder '_exit()' oder etwas Ähnliches aufruft, das das Programm stoppt. Im Beispielcode ist die einzige Funktion, die innerhalb von 'foo()' aufgerufen wird, 'bar()' - und das ist ein Standardkonstruktor für den 'enum bar {...};' -Typ. Es ist nicht sofort offensichtlich, warum das nicht zurückkehren würde - und wenn dies der Fall ist, würde die Funktion "foo()" zurückkehren, so dass das "noreturn" -Attribut unpassend wäre. –