2012-11-19 18 views
22

Un modo per implementare gli avvisi di deprecazione consiste nel produrre avvisi sulle chiamate alle funzioni deprecate, a meno che non si stia chiamando da un contesto deprecato. In questo modo il codice legacy può chiamare il codice legacy senza produrre avvertimenti che equivalgono solo al rumore.Come posso eliminare gli avvisi obsoleti in funzioni deprecate in GCC?

Questa è una linea di pensiero ragionevole, e si riflette nelle implementazioni che vedo in GCC 4.2 (1) e in Clang 4.0 (2) su OS X e in Clang 3.0 (3) su Ubuntu.

  • (1): i686-apple-darwin11-LLVM-g ++ - 4.2 (GCC) 4.2.1 (Basato su Apple Inc. costruire 5658) (LLVM costruire 2336.11.00)
  • (2): Apple clang versione 4.0 (tag/Apple/clang-421.0.57) (basato su LLVM 3.1svn)
  • (3): Ubuntu clang versione 3.0-6ubuntu3 (tag/RELEASE_30/finale) (basato su LLVM 3.0)

Tuttavia, quando compilo con GCC 4.6 avvertenze (4) su Ubuntu, ottengo deprecato per tutte le chiamate di deprecat funzioni ed, indipendentemente dal contesto. È una regressione nella funzionalità? Ci sono opzioni del compilatore che posso usare per ottenere l'altro comportamento?

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

Esempio:

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 
} 

uscita da GCC 4.2 (Sì, Ricevo lo stesso avvertimento due volte, ma non me ne importa niente:

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) 

uscita dal 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] 

Come posso convincere il GCC 4.6 che dovrebbe darmi lo stesso output come GCC 4.2?

+0

È assolutamente possibile che questo non abbia mai funzionato con GCC di FSF, che il comportamento 4.2 che si sta vedendo è una patch Apple per GCC. Ti capita di avere FSF GCC 4.2 installato ovunque per controllare? – hvd

+0

@hvd Hai ragione. Mi piacerebbe vedere quel test, ma non ho 4.2 a portata di mano:/ –

risposta

11

Il comportamento che si vede in GCC 4.2 è causato da una patch specifica di Apple per GCC. GF 4.2.4 di FSF avverte sull'uso di a.Il bit specifica che Apple ha GCC che FSF GCC fa non è:

--- 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)); 

(Disponibile in GPLv2 o successiva)

Si potrebbe desiderare di adattare questa patch per una versione successiva di GCC (forse nessuna modifica sono necessari, forse sono necessarie importanti modifiche) e compilare GCC dal sorgente con questa patch applicata. Oppure puoi segnalarlo come una richiesta di funzionalità sul bugzilla GCC di FSF.

+0

Neat! Questa è una buona risposta. Penso che farò questa richiesta di funzionalità. Dove hai trovato il diff? –

+0

Scarica i sorgenti FSF, scarica i sorgenti Apple, disimballa entrambi, affronta una diff ricorsiva, cerca "deprecato" nei risultati e sperare che non ci siano troppi risultati :) – hvd

+0

Hehe, capito. Dovrò pianificare il tempo per quello ... :) Grazie! –

26

-Wno-deprecated rimuoverà tutte le avvertenze deprecati

+10

Questo non è ciò che l'OP sta chiedendo. – OmnipotentEntity

+1

@OnnipotenteEntity, perché no? Si compila il codice legacy con '-Wno-deprecated' e il nuovo codice senza. – Lol4t0

+4

La tua affermazione è senza dubbio vera, ma questo * non è * quello che sto chiedendo. I * do * vogliono gli avvisi di deprecazione GCC 4.2. –

24

gcc 4.6 aggiunto pragma diagnostici che vi aiuterà a risolvere questo problema:

#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 

Nota: questo funziona solo in gcc 4.6 e superiori. push e pop sono 4.6 estensioni. Con gcc 4.5, gli #pragma GCC diagnostic push e pop verranno ignorati (con avvisi). Quello che non verrà ignorato è il #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - ma ora ha effetto fino alla fine del file.

+1

+1 - Questa è una soluzione davvero buona per chi non vuole o non è in grado di applicare patch a GCC. – Riot

1

Ho riscontrato lo stesso problema. La soluzione che si avvicinò è la seguente

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 
} 

Così ho appena rinominare la mia classe in una classe di OLD_A_NOT_TO_BE_USED. Ricevo l'avviso solo al ritorno b(); e se qualcuno stava usando a, otterrà comunque l'avvertimento deprecato.

Problemi correlati