Tại sao GCC cảnh báo tôi về lỗi dự phòng ngay cả khi tôi sử dụng [[dự phòng]]?


86

Trong đoạn mã sau, tôi sử dụng [[fallthrough]]thuộc tính tiêu chuẩn từ C ++ 1z để ghi lại rằng mong muốn có một đường dự phòng:

#include <iostream>

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

Với GCC 7.1, mã biên dịch không có lỗi. Tuy nhiên, trình biên dịch vẫn cảnh báo tôi về một lỗi:

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

Tại sao?


33
Và tôi đã ở đây, nghĩ rằng các bạn C ++ không thể làm mọi thứ xấu xí hơn được nữa!
SnakeDoc

3
@SnakeDoc: Đó là một món quà!
Deduplicator:

3
@SnakeDoc Đó phải là một nhận xét về câu trả lời, điều này khiến nó thậm chí còn tệ hơn. :)

23
Tôi không đồng ý với những phiếu bầu sát sao. Lý do "một lỗi đánh máy đơn giản" tồn tại đối với các trường hợp sự cố của OP chỉ xảy ra do một số lỗi không liên quan đến mô tả câu hỏi và sẽ không hữu ích cho bất kỳ ai khác. Trong trường hợp này, rất có thể người khác quên dấu chấm phẩy ở chỗ đó, mắc lỗi tương tự và tìm câu hỏi này khi tìm giải pháp.
CodesInChaos

14
Tôi thực sự không thích nhận xét của tôi đã bị xóa khỏi câu hỏi này vì vậy tôi buộc phải lặp lại nó một lần nữa - trong khi đây thực sự là một lỗi đánh máy, rất có thể người dùng khác sẽ lặp lại nó, tìm kiếm nó và tìm thấy câu hỏi này với câu trả lời này. Như vậy, nó vừa là một câu hỏi hay, câu trả lời hay và đáng được bỏ ngỏ.
Barry

Câu trả lời:


105

Bạn thiếu dấu chấm phẩy sau thuộc tính:

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

Các [[fallthrough]]thuộc tính là được áp dụng cho một tuyên bố rỗng (xem P0188R1 ). Thân cây Clang hiện tại đưa ra một lỗi hữu ích trong trường hợp này :

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

Cập nhật: Cody Gray đã báo cáo vấn đề này cho nhóm GCC.


Đề cập đến những gì thuộc tính áp dụng mà không có dấu chấm phẩy sẽ rất hay. Tôi cho rằng đó là trường hợp tiếp theo?
CodesInChaos

2
@CodesInChaos fallthrough attribute is only allowed on empty statements; vì nó không được theo sau bởi một tuyên bố trống rỗng, gcc chỉ đơn giản là bỏ qua nó
musicman523

2
@ musicman523 Điều đó ... có vẻ ... sai? Dường như, sẽ tốt hơn nếu yêu cầu dấu chấm phẩy ngay cả khi được theo sau bởi một câu lệnh trống và chỉ cần từ chối biên dịch theo cách khác.
SnakeDoc

@SnakeDoc Rõ ràng nó chỉ là một trường hợp cụ thể của các thuộc tính câu lệnh, vì vậy trình phân tích cú pháp cho phép nó thông qua, nhưng nó không có bất kỳ ngữ nghĩa nào khi áp dụng cho một câu lệnh không rỗng. Hãy coi đó là một lỗi nếu bạn muốn và clangsửa nó.
Barmar

2
@CodesInChaos Nếu không có dấu chấm phẩy, thuộc tính sẽ gắn với nhãn.
TC
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.