2012-11-19 6 views
22

Eine Möglichkeit zur Implementierung von Verwarnungswarnungen besteht darin, Warnungen bei Aufrufen veralteter Funktionen zu erzeugen, sofern Sie nicht von einem veralteten Kontext aus aufrufen. Auf diese Weise kann Legacy-Code Legacy-Code aufrufen, ohne Warnungen zu erzeugen, die nur Rauschen darstellen.Wie kann ich veraltete Warnungen in veralteten Funktionen in GCC loswerden?

Dies ist eine vernünftige Linie des Denkens, und es spiegelt sich in den Implementierungen, die ich in GCC 4.2 (1) und Clang 4.0 (2) auf OS X sowie Clang 3.0 (3) auf Ubuntu.

  • (1): i686-apple-darwin11-llvm-g ++ - 4.2 (GCC) 4.2.1 (Basierend auf Apple Inc. bauen 5658) (LLVM bauen 2336.11.00)
  • (2): Apple Clang Version 4.0 (Tags/Apple/clang-421.0.57) (basierend auf LLVM 3.1svn)
  • (3): Ubuntu Clang Version 3.0-6ubuntu3 (Tags/RELEASE_30/endgültig) (basierend auf LLVM 3.0)

Allerdings, wenn ich mit GCC 4.6 (4) auf Ubuntu kompilieren, ich veraltet Warnungen erhalten für alle Aufrufe von deprecat ed Funktionen, unabhängig vom Kontext. Ist das eine Regression in der Funktionalität? Gibt es Compileroptionen, die ich verwenden kann, um das andere Verhalten zu erhalten?

  • (4): g ++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

Beispielprogramm:

int __attribute__((deprecated)) a() { 
    return 10; 
} 

int __attribute__((deprecated)) b() { 
    return a() * 2; //< I want to get rid of warnings from this line 
} 

int main() { 
    return b(); //< I expect a warning on this line only 
} 

Output von GCC 4.2 (ja, Ich bekomme die gleiche Warnung zweimal, aber das interessiert mich nicht):

main.cpp: In function ‘int main()’: 
main.cpp:10: warning: ‘b’ is deprecated (declared at main.cpp:5) 
main.cpp:10: warning: ‘b’ is deprecated (declared at main.cpp:5) 

Ausgabe von GCC 4.6:

main.cpp: In function 'int b()': 
main.cpp:6:9: warning: 'int a()' is deprecated (declared at main.cpp:1) [-Wdeprecated-declarations] 
main.cpp:6:11: warning: 'int a()' is deprecated (declared at main.cpp:1) [-Wdeprecated-declarations] 
main.cpp: In function 'int main()': 
main.cpp:10:9: warning: 'int b()' is deprecated (declared at main.cpp:5) [-Wdeprecated-declarations] 
main.cpp:10:11: warning: 'int b()' is deprecated (declared at main.cpp:5) [-Wdeprecated-declarations] 

Wie kann ich überzeugen 4.6 GCC, dass sie die gleiche Leistung wie GCC 4.2 geben Sie mir sollte?

+0

Es ist durchaus möglich, dass dies nie mit FSF GCC funktioniert hat, dass das 4.2 Verhalten, das Sie sehen, ein Apple-Patch für GCC ist. Haben Sie zufällig irgendwo FSF GCC 4.2 installiert? – hvd

+0

@hvd Sie haben Recht. Ich würde gerne diesen Test sehen, aber ich habe keine 4.2 zur Hand:/ –

Antwort

11

Das Verhalten in GCC 4.2 wird durch einen Apple-spezifischen Patch für GCC verursacht. FSF GCC 4.2.4 warnt vor der Verwendung von a.Die spezifische Bit, dass Apple GCC hat, dass FSF GCC nicht heißt:

--- a/gcc/toplev.c 
+++ b/gcc/toplev.c 
@@ -902,6 +902,9 @@ warn_deprecated_use (tree node) 
    if (node == 0 || !warn_deprecated_decl) 
    return; 

+ if (current_function_decl && TREE_DEPRECATED (current_function_decl)) 
+ return; 
+ 
    if (DECL_P (node)) 
    { 
     expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (node)); 

(erhältlich unter GPLv2 oder später)

Möglicherweise möchten Sie diesen Patch auf eine neuere Version von GCC anzupassen (vielleicht keine Änderungen werden benötigt, vielleicht sind größere Änderungen erforderlich), und erstellen GCC aus der Quelle mit diesem Patch angewendet. Oder Sie melden dies als eine Feature-Anfrage bei FSF GCC bugzilla.

+0

Ordentlich! Das ist eine ziemlich gute Antwort. Ich denke, ich werde dies zu einer Feature-Anfrage machen. Wo hast du den Unterschied gefunden? –

+0

Laden Sie FSF-Quellen herunter, laden Sie Apple-Quellen herunter, entpacken Sie beide nebeneinander, führen Sie einen rekursiven Vergleich durch, suchen Sie nach "deprecated" in den Ergebnissen und hoffen, dass es nicht zu viele Ergebnisse gibt :) – hvd

+0

Hehe, hab es. Ich werde dafür Zeit einplanen müssen ... :) Danke! –

26

-Wno-deprecated werden alle veralteten Warnungen

+10

Das ist nicht, was OP verlangt. – OmnipotentEntity

+1

@OmnipotentEntity, warum nicht? Sie kompilieren alten Code mit "-Wno-deprecated" und neuen Code ohne. – Lol4t0

+4

Ihre Aussage ist zweifellos richtig, aber das ist * so nicht * was ich verlange. Ich möchte die Verwarnungswarnungen, die GCC 4.2 gibt. –

24

gcc 4.6 hinzugefügt Diagnose pragmas entfernen, die dieses Problem lösen helfen:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 
int __attribute__((deprecated)) b() { 
    return a() * 2; //< I want to get rid of warnings from this line 
} 
#pragma GCC diagnostic pop 

Hinweis: Dies funktioniert nur in gcc 4.6 und höher. Die push und pop sind 4.6 Erweiterungen. Mit gcc 4.5 werden die #pragma GCC diagnostic push und pop ignoriert (mit Warnungen). Was nicht ignoriert wird, ist die #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - aber jetzt hat dies Wirkung bis zum Ende der Datei.

+1

+1 - Dies ist eine wirklich gute Lösung für diejenigen, die GCC nicht patchen wollen oder wollen. – Riot

1

Ich stoße auf das gleiche Problem. Die Lösung, die aufkam ist die folgende

typedef OLD_A_NOT_TO_BE_USED a __attribute__((deprecated)); 

int OLD_A_NOT_TO_BE_USED() { 
    return 10; 
} 

int __attribute__((deprecated)) b() { 
    return OLD_A_NOT_TO_BE_USED() * 2; //< I want to get rid of warnings from this line 
} 

int main() { 
    return b(); //< I expect a warning on this line only 
} 

Also ich meine, eine Klasse nur umbenennen in OLD_A_NOT_TO_BE_USED Klasse. Ich bekomme die Warnung nur bei der Rückkehr b(); und wenn jemand ein verwendet, erhalten sie immer noch die veraltete Warnung.