Vô hiệu hóa có chọn lọc cảnh báo GCC chỉ cho một phần của đơn vị dịch?


85

GCC gần nhất tương đương với mã tiền xử lý MSVC này là gì?

#pragma warning( push )                    // Save the current warning state.
#pragma warning( disable : 4723 )          // C4723: potential divide by 0
// Code which would generate warning 4723.
#pragma warning( pop )                     // Restore warnings to previous state.

Chúng tôi có mã trong các tiêu đề thường được bao gồm mà chúng tôi không muốn tạo cảnh báo cụ thể. Tuy nhiên, chúng tôi muốn các tệp bao gồm các tiêu đề đó tiếp tục tạo ra cảnh báo đó (nếu dự án đã bật cảnh báo đó).


Nếu các tiêu đề được cài đặt thành / usr / include hoặc những gì bạn có, gcc không tạo cảnh báo cho chúng theo mặc định.
Spudd86

Câu trả lời:


95

Điều này có thể xảy ra trong GCC kể từ phiên bản 4.6 hoặc khoảng tháng 6 năm 2010 trong thân cây.

Đây là một ví dụ:

#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wuninitialized"
    foo(a);         /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(b);         /* no diagnostic for this one */
#pragma GCC diagnostic pop
    foo(c);         /* error is given for this one */
#pragma GCC diagnostic pop
    foo(d);         /* depends on command line options */

8
Chức năng đẩy và bật đã được thêm vào gcc 4.6 ( gcc.gnu.org/onlineocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html ).
Dave Johansen

Có thể bạn sẽ muốn đẩy hai lần nếu bạn sắp bật hai lần.
Dan

2
@Dan: Đọc hướng dẫn sử dụng và nhận xét. Lưu ý nguồn gốc của ví dụ.
Matt Joiner

FYI cho các phiên bản cũ hơn như 4.4.7, bạn vẫn có thể sử dụng #pragma GCC diagnostic [error|warning|ignored]nhưng popkhông được triển khai / hỗ trợ.
Trevor Boyd Smith

36

Điều gần nhất là pragma chẩn đoán GCC , #pragma GCC diagnostic [warning|error|ignored] "-Wwhatever". Nó không gần với những gì bạn muốn, và hãy xem liên kết để biết chi tiết và cảnh báo.


1
Bạn có biết lý do để không thêm tính năng này là gì và ở đâu không? (Tôi không thể tìm thấy nó.) Tôi thấy cửa sổ bật-tắt-đẩy-vô-hiệu-hoá cảnh báo rất hữu ích.

1
Tôi không thực sự tưởng tượng rằng "không thêm tính năng" vào gcc có xu hướng có lý do chính đáng như việc không có ai gửi bản vá đang hoạt động.
hỗn loạn

14
Không phải là không ai sẵn sàng làm công việc cho loại kiểm soát cảnh báo chi tiết này trong gcc hoặc gửi mã - tôi biết về một tập đoàn lớn ở Thung lũng Silicon đã làm điều này và một công ty khác sẽ rất vui khi trả tiền cho ai đó để làm điều đó và nhận mã vào luồng. Thay vào đó, mỗi cuộc thảo luận với một anh chàng (với tư cách là một trong những người bảo trì gdb) được cắm vào công cụ này, những người bảo trì gcc có một triết lý: "Nếu có một cảnh báo, đó là một lỗi và bạn cần phải sửa nó." Vì vậy, (imo) đó là một cuộc tranh cãi tôn giáo, và họ kiểm soát mã để họ giành chiến thắng.
Bob Murphy

Thêm vào nhận xét của Bob, các nhà phát triển GCC có lịch sử không thích #pragmachỉ thị, vì vậy bất kỳ thứ gì dành riêng cho GCC có thể sẽ được triển khai dưới dạng một __attribute__((foo)).
Tom

10
gcc mới (> = 4.4) có #pragma GCC push_optionsđể bạn có thể muck về với nhiều hơn chỉ là chẩn đoán ... gcc.gnu.org/onlinedocs/gcc/...
Spudd86

33

Tôi đã làm một cái gì đó tương tự. Đối với mã của bên thứ ba, tôi không muốn thấy bất kỳ cảnh báo nào. Vì vậy, thay vì chỉ định -I/path/to/libfoo/include, tôi đã sử dụng -isystem /path/to/libfoo/include. Điều này làm cho trình biên dịch coi các tệp tiêu đề đó là "tiêu đề hệ thống" nhằm mục đích cảnh báo và miễn là bạn không bật -Wsystem-headers, hầu như bạn vẫn an toàn. Tôi vẫn thấy một vài cảnh báo bị rò rỉ từ đó, nhưng nó cắt giảm phần lớn nội dung rác.

Lưu ý rằng điều này chỉ hữu ích nếu bạn có thể tách mã vi phạm bằng thư mục bao gồm. Nếu nó chỉ là một tập hợp con của dự án của riêng bạn hoặc được trộn lẫn với mã khác, bạn không gặp may.


1
Mẹo hay. Nếu sử dụng LLVM, hãy thêm cờ -isystem dưới "Cờ C khác" trong phần "Trình biên dịch LLVM của Apple - Ngôn ngữ".
Nestor

@Tom Cảm ơn bạn đã chia sẻ. Tôi không thể hiểu nơi sử dụng giải pháp của bạn. Bạn có thể nói thêm một chút không?
Lorenzo B

1

Đây là phần mở rộng cho câu trả lời của Matt Joiner .

Nếu bạn không muốn tạo tôm trên toàn bộ mã của mình, bạn có thể sử dụng toán tử _Pragma :

#ifdef __GNUC__
#  define DIAGNOSTIC_ERROR(w) _Pragma("GCC diagnostic error \"" w "\"")
#  define DIAGNOSTIC_IGNORE(w) _Pragma("GCC diagnostic ignore \"" w "\"")
#  define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
#  define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#endif
// (...)

DIAGNOSTIC_ERROR("-Wuninitialized")
foo(a); // Error

DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE("-Wuninitialized")
foo(a); // No error

DIAGNOSTIC_POP
foo(a); // Error
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.