Làm thế nào để ngăn chặn cảnh báo GCC từ các tiêu đề thư viện?


126

Tôi có một dự án sử dụng các thư viện log4cxx, boost, v.v. có tiêu đề tạo ra nhiều cảnh báo (lặp đi lặp lại). Có cách nào để ngăn chặn các cảnh báo từ thư viện bao gồm (ví dụ #include <some-header.h>) hoặc bao gồm từ các đường dẫn nhất định không? Tôi muốn sử dụng -Wall và / hoặc -Wextra như bình thường trên mã dự án mà không bị che khuất thông tin liên quan. Tôi hiện đang sử dụng grep để tạo đầu ra nhưng tôi muốn thứ gì đó tốt hơn.

Câu trả lời:


127

Bạn có thể thử bao gồm các tiêu đề thư viện bằng cách sử dụng -isystemthay vì -I. Điều này sẽ khiến họ trở thành "người đứng đầu hệ thống" và GCC sẽ không báo cáo cảnh báo cho họ.


11
Nếu bạn đang cố gắng thực hiện điều này trong XCode thì hãy gắn đường dẫn hệ thống vào "các cờ C ++ khác" trong "cờ trình biên dịch tùy chỉnh" trong cài đặt xây dựng mục tiêu của bạn.
Matt Parkins

3
Một nhược điểm tiềm năng là trên một số nền tảng, g ++ sẽ tự động bao bọc mọi tiêu đề hệ thống extern "C", dẫn đến các lỗi kỳ lạ về liên kết C nếu bạn #includecó tiêu đề C ++ trong một -isystemđường dẫn.
Tavian Barnes

1
+1 đã giúp tôi giải quyết các vấn đề với cảnh báo tăng cường gây phiền nhiễu stackoverflow.com/questions353704753/warnings-from-boost
mrgloom

3
Tại sao điều này có nhiều phiếu bầu hơn so với câu trả lời của chính OP đã nói chính xác điều tương tự 1,5 giờ trước đó?
gạch dưới

1
Đối với Xcode: Điều gì xảy ra nếu không có đường dẫn thư mục trong "Các cờ C ++ khác" trong cài đặt xây dựng mục tiêu của tôi? Ai đó có thể giải thích về giải pháp này?
Ossir

107

Đối với những người sử dụng CMake, bạn có thể sửa đổi các include_directorieschỉ thị của mình để bao gồm biểu tượng SYSTEMngăn chặn các cảnh báo chống lại các tiêu đề đó.

include_directories(SYSTEM "${LIB_DIR}/Include")
                    ^^^^^^

Điều gì xảy ra nếu thư viện cung cấp một ${LIBFOO_USE_FILE}biến được sử dụng với lệnh include () của CMake ?
waldyrious

2
Đây dường như là giải pháp cho vấn đề của tôi. Tôi có 1.) mục tiêu nhị phân, phụ thuộc vào 2.) mục tiêu chỉ được viết bởi chính tôi, phụ thuộc vào 3.) một số thư viện bên ngoài. Tôi không biết làm thế nào để chỉ nhận được cảnh báo cho 1 & 2. Bạn có ý tưởng gì không?
knedlsepp

2
Dường như không hoạt động. Tôi đã thử điều này với một dự án sử dụng easylogging++và tôi nhận được cùng một lượng lớn cảnh báo từ easylogging++.hthư mục mặc dù thư mục chứa nó đã được bao gồm SYSTEMtùy chọn.
rbaleksandar

Cảm ơn rất nhiều vì điều này. Nó đã cứu tôi khỏi các trang và trang cảnh báo.
Svalorzen

1
Nhận xét tương tự như đối với câu trả lời được chấp nhận: đây là thực tế xấu đối với tôi.
Raffi

55

Bạn có thể sử dụng các pragma. Ví dụ:

// save diagnostic state
#pragma GCC diagnostic push 

// turn off the specific warning. Can also use "-Wall"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>

// turn the warnings back on
#pragma GCC diagnostic pop

3
Chỉ khả dụng với GCC> = 4.6
Caduchon

1
Tôi yêu khả năng của pragmas đẩy / pop. tôi nhớ một cái gì đó giống như java có sẵn từ nhiều năm trước và bị thất vọng / ghen tị với C / C ++. tôi thích cái này có sẵn tronggcc
Trevor Boyd Smith

@TrevorBoydSmith MS clcũng có khả năng trong nhiều năm ... Đôi khi gcchơi chậm để thích nghi.
Alexis Wilke

29

Tôi tìm thấy mánh khóe. Đối với thư viện bao gồm, thay vì -Idirsử dụng -isystem dirtrong tệp thực hiện. GCC sau đó xử lý boost, v.v. vì hệ thống bao gồm và bỏ qua mọi cảnh báo từ họ.


Lưu ý rằng nếu bạn sử dụng tiêu đề được biên dịch trước, bạn cần thêm cờ khi bạn biên dịch cả tiêu đề và mã.
dùng202729

9

#pragmalà hướng dẫn cho trình biên dịch. bạn có thể đặt thứ gì đó trước #incoide và tắt nó sau.

Bạn cũng có thể làm điều đó tại dòng lệnh .

Một trang GCC khác đặc biệt về việc vô hiệu hóa các cảnh báo .

Tôi sẽ đi cho các tùy chọn sử dụng của # pragma bên trong mã nguồn, và sau đó cung cấp một âm thanh lý (như là một bình luận) về việc tại sao bạn đang vô hiệu hóa các cảnh báo. Điều này có nghĩa là lý do về các tập tin tiêu đề.

GCC tiếp cận điều này bằng cách phân loại các loại cảnh báo. Bạn có thể phân loại chúng để được cảnh báo hoặc bị bỏ qua. Các bài viết được liên kết trước đó sẽ cho bạn thấy những cảnh báo nào có thể bị vô hiệu hóa.

Lưu ý: bạn cũng có thể xoa bóp mã nguồn để ngăn các cảnh báo nhất định bằng cách sử dụng các thuộc tính ; tuy nhiên, điều này ràng buộc bạn khá chặt chẽ với GCC.

Lưu ý 2: GCC cũng sử dụng giao diện pop / đẩy như được sử dụng trong trình biên dịch của microsoft - Microsoft vô hiệu hóa các cảnh báo thông qua giao diện này. Tôi đề nghị bạn điều tra thêm về điều này, vì tôi không biết liệu nó có khả thi hay không.


Tôi đã xem xét các pragma nhưng nếu tôi loại bỏ cảnh báo trước khi bao gồm một tiêu đề, làm cách nào để đặt nó trở lại trạng thái trước đó sau #include? Tôi muốn xem tất cả các cảnh báo cho mã dự án (đã giúp tôi một vài lần) nhưng có quyền kiểm soát từ dòng lệnh.
AdSR

4

Bạn có thể thử sử dụng các tiêu đề được biên dịch trước . Cảnh báo sẽ không biến mất nhưng ít nhất là sẽ không xuất hiện trong phần tổng hợp chính của bạn.


1
Đây thực sự có thể là một ý tưởng tốt. Bên thứ ba bao gồm không thay đổi mỗi ngày.
AdSR

Chính xác. Mặc dù tôi chưa sử dụng chúng nhiều trong Linux, nhưng chúng hoạt động khá tốt trên Visual Studio.
Pablo Santa Cruz

Không, chúng vẫn sẽ hiển thị trong phần biên dịch trừ khi bạn sử dụng một số cách khác để triệt tiêu chúng (chẳng hạn như -isystem, nhưng hãy nhớ sử dụng cả trong việc biên dịch tiêu đề và trong mã)
user202729

2

Nếu bạn cần ghi đè một cách rõ ràng một tiêu đề hệ thống thì bạn bị hạn chế đối với các pragma. Bạn có thể xác minh bao gồm bạn đang sử dụng thông qua make dependđầu ra.

Đồng thời xem phần chẩn đoán đẩy cho gcc> = 4.6


1

Đặt như sau

#pragma GCC system_header

sẽ tắt cảnh báo GCC cho tất cả các mã sau trong tệp này.


-9

Phải có lý do cho những cảnh báo đó. Những điều này sẽ được gây ra bởi lỗi trong mã của bạn sử dụng thư viện hoặc do lỗi trong chính mã thư viện. Trong trường hợp đầu tiên, sửa mã của bạn. Trong trường hợp thứ hai, hoặc ngừng sử dụng thư viện hoặc nếu đó là mã FOSS, hãy sửa nó.


+1 cho lời khuyên tốt: D nhưng anh ấy đang hỏi cách làm một cái gì đó cụ thể: D
Hassan Syed

4
Một số cảnh báo là không thể hoặc rất khó khắc phục, đặc biệt là trong mã của bên thứ 3, đặc biệt là trong mã giàu lập trình siêu dữ liệu như Boost's.
ulidtko

3
Tệ hơn nữa, cái đang làm tôi khó chịu là "tuyên bố 'c' làm mờ đi một thành viên của 'this' [-Werror = Shadow]" sâu, sâu trong một số tiêu đề tăng cường. Đó chắc chắn không phải là một vấn đề, nhưng nó và các vấn đề tương tự đang xuất hiện đầu ra và khiến tôi khó tìm thấy các trường hợp thực sự là một cái bóng trong cơ sở mã của chúng tôi.
dmckee --- ex-moderator mèo con
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.