2015-07-20 12 views
19

Wir haben vor kurzem -Wall für ein Projekt aktiviert. Es ist aktiviert, wenn GCC bei 4.7 oder höher (oder Clang) ist, weil wir GCC diagnostic verwenden können, um die Ausgabe der erhöhten Warnungen zu verwalten. Wir wollen sie aus dem Quellcode verwalten, und nicht über Befehlszeilenargumente. (Wir wollen die Befehlszeile nicht verschmutzen oder Bibliotheksbenutzer bitten, wieder zu entdecken, was benötigt wird).GCC nicht 'Pragma GCC-Diagnose' zu Schweigen Warnungen

Unter GCC 4.8 und 5.1, wir fangen Warnungen, die für -Wunused-variable, in einem GCC Diagnoseblock deaktiviert wurden -Wunused-value, -Wunused-function und -Wunknown-pragmas. Beide GCCs akzeptieren -fopenmp, und beide definieren _OPENMP als Reaktion auf sie, so dass ich bin ziemlich sicher, es sollten wir nie eine -Wunknown-pragmas in Reaktion auf #prgam omp ... sehen (es ist deaktiviert, aber es ist nicht unbekannt).

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 
^ 
... 

In diesem speziellen Fall die file nbtheroy.cpp hat folgende Wache an seinem Platz zu helfen zu verwalten (angezeigt, nur relevante Teile aber man kann alles von the GitHub link sehen), dass die Warnung:

// 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); 
} 
... 

Da die Datei ist *.cpp (seine effektiv die Übersetzungseinheit), wir nicht eines führen #pragma GCC diagnostic push am Anfang und #pragma GCC diagnostic pop am Ende. (Wir machen das für Header-Dateien, die jedoch enthalten sind). (Wir haben es auch versucht, aber es hat nicht geholfen).

Und hier ist GCC_DIAGNOSTIC_AWARE (von 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__)) 

Ich weiß, dass die Wache arbeitet, weil das Hinzufügen einer #error in dem Block einen Fehler verursacht. Auch das Auskommentieren der Wache und das Rufen #pragma GCC diagnostic ignored "-Wunknown-pragmas" hilft nicht. Schließlich funktioniert es unter Clang gut.

Ich erfahre es auch für andere Warnungen, wie -Wunused-variable, -Wunused-value und -Wunused-function. I wirklich möchte nicht die Befehlszeile verschmutzen, wie mit dem potenziellen Duplikat vorgeschlagen.

Wie bekomme ich den GCC pragma diagnostic Mechanismus wie erwartet funktioniert, um Warnungen unter GCC stumm zu schalten, wenn -Wall verwendet wird?


Verwandte, wenn Sie es (seine GNUmakefile basiert und keine Konfigurationen oder Autotools erforderlich) reproduzieren wollen:

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

EDIT: wir eingecheckt in einem Patch, der -Wall deaktiviert außer für Clang. Wenn Sie das alte Verhalten reproduzieren wollen, dann:

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

Ich würde vorschlagen, zuerst die '# if/# endif' (nur die' #pragma GCC ... ') zu entfernen, um zu sehen, ob es ein Problem mit' GCC_DIAGNOSTIC_AWARE' ist. – paxdiablo

+0

möglich Duplikat von [Unterdrücken -Wunknown-Pragmas Warnung in GCC] (http://StackOverflow.com/Questions/12842306/Suppress-WunkNown-Pragmas-Warning-in-GCC) – nneonneo

+0

@ Paxdiablo - Keine Freude. Ich habe den Wächter deaktiviert und "#pragma GCC diagnostic ignored" -Wunknown-pragmas "' direkt aufgerufen. – jww

Antwort

9

Dies scheint ein Fehler in gcc zumindest zu sein.Der folgende Code:

#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(); 
} 

keine Probleme hat die uninitialised x Wert ignoriert aber klagt immer noch über die Pragma (ohne uninitialized Pragma, erzeugt es eine Warnung für x wie man erwarten würde).

Wenn Sie die Befehlszeilenoptionen auf -Wall -Wno-unknown-pragmas ändern, ignoriert es es einfach gut. Das ist in Ordnung für Ihren speziellen Fall, da Sie möchten, dass es über Ihre gesamte Übersetzungseinheit angewendet wird, aber es wird nicht die feinkörnige Kontrolle zulassen, die Sie von der Methode #pragma erhalten würden (wenn es funktioniert).


Ich ging einen Fehlerbericht auf GCC zu erhöhen, aber festgestellt, dass es existiert bereits (#53431).

Während der spezifische Fehler mit -Wundef zu tun hat, zeigt ein Ausschnitt in einen der Kommentare, dass es wahrscheinlich auf alle Varianten gilt den Präprozessor zu beeinflussen (leicht zur Betonung modifiziert):

Der C++ Parser Lexes (und Preprocesses) vor der Behandlung der Pragmas, während der C-Parser die Pragmas so verarbeitet, wie sie es sehen.

Wir müssen diese Pragmas auch in cp/parser.c:631 irgendwie analysieren. Vielleicht kann man etwas tun, was dem ähnlich ist, was wir für cp_parser_initial_pragma machen, aber innerhalb der Schleife und nur mit der Pragma-Diagnose umgehen. Sicherlich wird es einige Versuche und Fehler brauchen, um es richtig zu machen. Wenn einer von euch es versuchen möchte und Hilfe benötigt, fragt einfach hier oder in der Mailingliste.

Das erklärt, warum wir das gleiche Problem mit -Wuninitialized nicht sehen, weil es während der späteren Phasen des Übersetzungsvorgangs erkannt hat, nachdem die Pragmas haben am Ende der Vorverarbeitung aktiviert.

Also, wenn Sie es rechtzeitig behoben sehen wollen (es wurde vor über drei Jahren erhoben), würde ich (wie ich) vorschlagen, die GCC bugzilla Seite zu hassen, um zu versuchen, etwas Exposition zu bekommen.

+0

Ja, das größere Problem ist der Bibliothekscode. Also müssen wir es reparieren, um an der Bibliothek selbst zu arbeiten. Es ist ein Convenience-Artikel für uns. Aber die Benutzer erwarten, dass es "nur funktioniert", wenn sie die Bibliothek einschließen. Wenn sie die Bibliothek enthalten und dann durch Befehlszeilen-Hoops springen müssen, weil die Dinge nicht funktionieren, dann ist das ein Problem. – jww

+0

@jww, wenn Sie eine Bibliothek freigeben ('.o/.a/.so/etc'), dann wird die Warnung sicher nicht auftreten. Oder besteht Ihre Bibliothek tatsächlich aus einer kompilierbaren Quelle? – paxdiablo

+0

Ja, die Quellen sind freigegeben.Außerdem erzeugen einige Header Warnungen und wir versuchen, sie mit der gleichen Methode zu deaktivieren. – jww

Verwandte Themen