2015-07-20 25 views
19

Gần đây, chúng tôi đã kích hoạt -Wall cho một dự án. Nó được kích hoạt khi GCC ở 4.7 hoặc cao hơn (hoặc Clang) vì chúng ta có thể sử dụng GCC diagnostic để quản lý đầu ra từ các cảnh báo nâng lên. Chúng tôi muốn quản lý chúng từ mã nguồn và không thông qua đối số dòng lệnh. (Chúng tôi không muốn gây ô nhiễm dòng lệnh hoặc yêu cầu người dùng thư viện tìm lại những gì cần thiết).GCC không tôn trọng 'pragma GCC diagnostic' để cảnh báo im lặng

Dưới GCC 4.8 và 5.1, chúng tôi đang bắt cảnh báo đã được vô hiệu hóa trong một khối chẩn đoán GCC cho -Wunused-variable, -Wunused-value, -Wunused-function-Wunknown-pragmas. Cả hai GCC chấp nhận -fopenmp, và cả hai xác định _OPENMP để đáp ứng với nó, vì vậy tôi khá chắc chắn nó không bao giờ chúng ta sẽ thấy một -Wunknown-pragmas để đáp ứng với #prgam omp ... (nó tàn tật, nhưng nó không phải là chưa biết).

g++ -DNDEBUG -g2 -O3 -Wall -march=native -pipe -c nbtheory.cpp 
nbtheory.cpp:655:0: warning: ignoring #pragma omp parallel [-Wunknown-pragmas] 
    #pragma omp parallel 
^ 
nbtheory.cpp:656:0: warning: ignoring #pragma omp sections [-Wunknown-pragmas] 
    #pragma omp sections 
^ 
... 

Trong trường hợp đặc biệt này, các file nbtheroy.cpp có bảo vệ sau tại chỗ để giúp quản lý cảnh báo rằng (chỉ bộ phận liên quan được hiển thị, nhưng bạn có thể nhìn thấy tất cả mọi thứ từ the GitHub link):

// Defines GCC_DIAGNOSTIC_AWARE if GCC 4.7 or above. 
#include <misc.h> 
... 

#if GCC_DIAGNOSTIC_AWARE 
# pragma GCC diagnostic ignored "-Wunknown-pragmas" 
#endif 

... 
Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, 
        const Integer &p, const Integer &q, const Integer &u) 
{ 
    Integer p2, q2; 
    #pragma omp parallel 
     #pragma omp sections 
     { 
      #pragma omp section 
       p2 = ModularExponentiation((a % p), dp, p); 
      #pragma omp section 
       q2 = ModularExponentiation((a % q), dq, q); 
     } 
    return CRT(p2, p, q2, q, u); 
} 
... 

Vì tệp là *.cpp (đơn vị đơn vị dịch hiệu quả), chúng tôi không thực hiện #pragma GCC diagnostic push ở đầu và #pragma GCC diagnostic pop ở cuối. (Tuy nhiên, chúng tôi thực hiện điều đó đối với các tệp tiêu đề được bao gồm). (Chúng tôi cũng đã cố gắng làm điều đó, nhưng nó không giúp ích gì).

Và đây là GCC_DIAGNOSTIC_AWARE (từ misc.h):

// Used to suppress some warnings in some header and implementation files. 
// Some platforms, like CentOS and OpenBSD, use old compilers that don't understand -Wno-unknown-pragma. 
#define GCC_DIAGNOSTIC_AWARE ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__clang__)) 

Tôi biết bảo vệ đang làm việc vì thêm một #error trong khối gây ra một lỗi. Ngoài ra, bình luận ra bảo vệ và gọi ra #pragma GCC diagnostic ignored "-Wunknown-pragmas" không giúp đỡ. Cuối cùng, nó hoạt động tốt dưới Clang.

Tôi cũng đang gặp phải các cảnh báo khác, như -Wunused-variable, -Wunused-value-Wunused-function. I thực sự không muốn gây ô nhiễm dòng lệnh như được đề xuất với bản sao tiềm năng.

Làm cách nào để có cơ chế GCC pragma diagnostic hoạt động như mong đợi để cảnh báo im lặng theo GCC khi sử dụng -Wall?


liên quan, nếu bạn muốn tái tạo nó (nó GNUmakefile dựa, và không đòi hỏi cấu hình hoặc autotools):

git clone https://github.com/weidai11/cryptopp.git cryptopp-warn 
cd cryptopp-warn 
make 

EDIT: chúng tôi kiểm tra trong một bản vá mà vô hiệu hóa -Wall trừ cho Clang. Nếu bạn muốn sao chép hành vi cũ, sau đó:

git clone https://github.com/weidai11/cryptopp.git cryptopp-warn 
cd cryptopp-warn 
export CXXFLAGS="-g2 -O3 -DNDEBUG -Wall" 
make 
+1

Tôi muốn đề xuất trước tiên xóa '# if/# endif' (chỉ để lại' #pragma GCC ... ') để xem đó có phải là vấn đề với' GCC_DIAGNOSTIC_AWARE' hay không. – paxdiablo

+0

bản sao có thể có của [Cảnh báo ngăn chặn -Wunknown-pragmas trong GCC] (http://stackoverflow.com/questions/12842306/suppress-wunknown-pragmas-warning-in-gcc) – nneonneo

+0

@paxdiablo - Không có niềm vui. Tôi vô hiệu hóa bảo vệ, và gọi ra '#pragma GCC chẩn đoán bỏ qua "-Wunknown-pragmas" 'trực tiếp. – jww

Trả lời

9

Điều này dường như là lỗi trong gcc ít nhất.Các mã sau đây:

#pragma GCC diagnostic ignored "-Wunknown-pragmas" 
#pragma GCC diagnostic ignored "-Wuninitialized" 

int fn(void) { 
    #pragma xyzzy 
    int x; 
    return x; 
} 

int main (void) { 
    return fn(); 
} 

không có vấn đề bỏ qua giá trị uninitialised x nhưng vẫn phàn nàn về pragma (không có uninitialized pragma, nó tạo ra một cảnh báo cho x như bạn mong muốn).

Nếu bạn thay đổi các tùy chọn dòng lệnh thành -Wall -Wno-unknown-pragmas, thì nó sẽ bỏ qua nó. Điều đó không quan trọng đối với trường hợp cụ thể của bạn vì bạn muốn nó được áp dụng trên toàn bộ đơn vị dịch của bạn nhưng nó sẽ không cho phép kiểm soát chi tiết mà bạn sẽ nhận được từ phương pháp #pragma (nếu nó hoạt động).


Tôi đã đưa ra báo cáo lỗi trên GCC nhưng thấy rằng nó đã tồn tại (#53431).

Trong khi đó lỗi cụ thể đã làm với -Wundef, một đoạn trong một trong những ý kiến ​​chỉ ra rằng nó có thể áp dụng cho tất cả các biến thể ảnh hưởng đến tiền xử lý (một chút thay đổi để nhấn mạnh):

C lexes phân tích cú pháp ++ ( tiền xử lý trước khi xử lý pragmas, trong khi trình phân tích cú pháp C xử lý các pragmas khi nó nhìn thấy chúng.

Chúng tôi phải phân tích cú pháp bằng cách nào đó các pragmas này cũng trong cp/parser.c:631. Có lẽ người ta có thể làm một cái gì đó tương tự như những gì chúng tôi làm cho cp_parser_initial_pragma, nhưng trong vòng lặp và chỉ xử lý chẩn đoán pragma. Chắc chắn, nó sẽ cần một số thử nghiệm và sai sót để làm cho nó đúng. Nếu bất kỳ ai trong các bạn muốn thử và cần sự giúp đỡ, chỉ cần hỏi ở đây hoặc trong danh sách gửi thư.

Điều đó giải thích tại sao chúng ta không nhìn thấy cùng một vấn đề với -Wuninitialized, bởi vì nó được phát hiện trong giai đoạn sau của quá trình biên soạn, sau khi pragmas đã được kích hoạt ở phần cuối của tiền xử lý. Vì vậy, nếu bạn muốn nhìn thấy nó cố định một cách kịp thời hơn (nó đã được nâng lên hơn ba năm trước), tôi muốn đề nghị (như tôi có) phức tạp các trang web bugzilla GCC để cố gắng có được một số tiếp xúc.

+0

Vâng, vấn đề lớn hơn là mã thư viện. Vì vậy, chúng ta cần sửa nó để làm việc trên chính thư viện. Đó là một mặt hàng tiện lợi cho chúng tôi. Nhưng người dùng mong đợi nó "chỉ hoạt động" khi chúng bao gồm thư viện. Nếu chúng bao gồm thư viện và sau đó phải nhảy qua hoops dòng lệnh bởi vì mọi thứ không hoạt động, thì đó là một vấn đề. – jww

+0

@jww, nếu bạn đang phát hành thư viện ('.o/.a/.so/etc'), thì cảnh báo sẽ không xảy ra chắc chắn. Hoặc thư viện của bạn có thực sự bao gồm nguồn có thể kết hợp được không? – paxdiablo

+0

Có, các nguồn được phát hành.Ngoài ra, một số tiêu đề tạo ra cảnh báo và chúng tôi cố gắng làm im lặng chúng bằng cùng một phương pháp. – jww

Các vấn đề liên quan