Чому GCC попереджає мене про провал, навіть коли я використовую [[провал]]?


86

У наступному фрагменті коду я використовую стандартний [[fallthrough]]атрибут із C ++ 1z, щоб задокументувати бажаність проходження:

#include <iostream>

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

У GCC 7.1 код компілюється без помилок. Однак компілятор все ще попереджає мене про провал:

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

Чому?


33
І ось я тут, думаючи, що ви, люди з С ++, не можете зробити щось потворнішим!
SnakeDoc

3
@SnakeDoc: Це подарунок!
Дедулікатор

3
@SnakeDoc Це повинен бути коментар до відповіді, що робить її ще гіршою. :)

23
Я не погоджуюсь із закритим голосуванням. Причина "простої друкарської помилки" існує в тих випадках, коли проблема OP сталася лише через якусь помилку, не пов'язану з описом питання, і не буде корисною для інших. У цьому випадку цілком ймовірно, що інші люди забувають крапку з комою в цьому місці, отримують ту саму помилку і знаходять це питання при пошуку рішення.
CodesInChaos

14
Мені дуже не подобається, що мій коментар було видалено з цього запитання, тому я змушений повторити його ще раз - хоча це справді друкарська помилка, дуже ймовірно, що інші користувачі повторять її, шукатимуть і знайдуть це питання за допомогою цієї відповіді. Як таке, це і гарне запитання, і хороша відповідь, і воно заслуговує на те, щоб його не відкривали.
Barry

Відповіді:


105

Вам не вистачає крапки з комою після атрибута:

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

[[fallthrough]]Атрибут повинні бути застосований до порожнього оператору (див P0188R1 ). Поточний стовбур Clang видає корисну помилку в цьому випадку :

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

Оновлення: Коді Грей повідомив про цю проблему команду GCC.


Згадувати, до чого відноситься атрибут без крапки з комою, було б непогано. Я припускаю, що мова йде про наступну справу?
CodesInChaos

2
@CodesInChaos fallthrough attribute is only allowed on empty statements; оскільки за ним не йде порожній вислів, gcc просто ігнорує його
musicman523

2
@ musicman523 Це ... здається ... неправильно? Здавалося б, було б більш розумним вимагати крапки з комою, навіть якщо за нею йде порожній вираз, і просто відмовитись компілювати інакше.
SnakeDoc

@SnakeDoc Очевидно, це лише окремий випадок атрибутів оператора, тому синтаксичний аналізатор дозволяє це зробити, але він не має жодної семантики при застосуванні до непустого оператора. Вважайте це помилкою, якщо хочете, та clangвиправте її.
Бармар,

2
@CodesInChaos Без крапки з комою атрибут належав би до мітки.
TC
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.