Dlaczego GCC ostrzega mnie o upadku, nawet gdy używam [[fallthrough]]?

86

W poniższym fragmencie kodu używam standardowego [[fallthrough]]atrybutu z C ++ 1z, aby udokumentować, że pożądane jest przejście:

#include <iostream>

int main() {
    switch (0) {
        case 0:
            std::cout << "a\n";
            [[fallthrough]]
        case 1:
            std::cout << "b\n";
            break;
    }
}

W GCC 7.1 kod kompiluje się bez błędu. Jednak kompilator nadal ostrzega mnie przed awarią:

warning: this statement may fall through [-Wimplicit-fallthrough=]
    std::cout << "a\n";
    ~~~~~~~~~~^~~~~~~~

Czemu?

s3rvac
źródło
33
I oto ja, myśląc, że wy, ludzie C ++, nie moglibyście uczynić rzeczy brzydszymi!
SnakeDoc,
3
@SnakeDoc: To prezent!
Deduplicator,
3
@SnakeDoc To powinien być komentarz do odpowiedzi, co jeszcze bardziej ją pogarsza. :)
23
Nie zgadzam się z głosami bliskimi. Powód „prosty błąd typograficzny” istnieje w przypadkach, gdy problem PO wystąpił tylko z powodu błędu niezwiązanego z opisem pytania i nie będzie przydatny dla nikogo innego. W tym przypadku jest całkiem prawdopodobne, że inni ludzie zapomną o średniku w tym miejscu, otrzymają ten sam błąd i znajdą to pytanie, szukając rozwiązania.
CodesInChaos
14
Zdecydowanie nie podoba mi się, że mój komentarz został usunięty z tego pytania, więc jestem zmuszony powtórzyć go ponownie - chociaż jest to rzeczywiście błąd typograficzny, jest bardzo prawdopodobne, że inni użytkownicy go powtórzą, wyszukają i znajdą to pytanie z tą odpowiedzią. W związku z tym jest to zarówno dobre pytanie, jak i dobra odpowiedź, i zasługuje na to, aby pozostać otwartym.
Barry,

Odpowiedzi:

105

Brakuje średnika po atrybucie:

case 0:
    std::cout << "a\n";
    [[fallthrough]];
    //             ^
case 1:

[[fallthrough]]Atrybut ma być stosowana do pustej rachunku (patrz P0188R1 ). Bieżący bagażnik Clang podaje pomocny błąd w tym przypadku :

error: fallthrough attribute is only allowed on empty statements
    [[fallthrough]]
      ^
note: did you forget ';'?
    [[fallthrough]]
                   ^
                   ;

Aktualizacja: Cody Gray zgłosił ten problem zespołowi GCC.

s3rvac
źródło
Dobrze byłoby wspomnieć, czego dotyczy atrybut, bez średnika. Zakładam, że to do następnej sprawy?
CodesInChaos
2
@CodesInChaos fallthrough attribute is only allowed on empty statements; ponieważ nie następuje po nim pusta instrukcja, gcc po prostu ją ignoruje
musicman523
2
@ musicman523 To ... wydaje się ... źle? Wydaje się, że rozsądniej byłoby wymagać średnika, nawet jeśli następuje po nim pusta instrukcja, i po prostu odmówić kompilacji w inny sposób.
SnakeDoc,
@SnakeDoc Najwyraźniej jest to tylko szczególny przypadek atrybutów instrukcji, więc parser pozwala na to, ale nie ma żadnej semantyki, gdy jest stosowany do instrukcji niepustej. Potraktuj to jako błąd, jeśli chcesz, i clangnapraw go.
Barmar
2
@CodesInChaos Bez średnika atrybut odnosiłby się do etykiety.
TC,