Sopprimi l'avviso di variabile inutilizzata in C++ => Bug del compilatore o bug del codice?
-
19-09-2019 - |
Domanda
Attualmente sto utilizzando il seguente modello di funzione per eliminare gli avvisi sulle variabili inutilizzate:
template<typename T>
void
unused(T const &) {
/* Do nothing. */
}
Tuttavia, durante il porting su Cygwin da Linux, ora ricevo errori del compilatore su g++ 3.4.4 (su Linux sono 3.4.6, quindi forse questa è una correzione di bug?):
Write.cpp: In member function `void* Write::initReadWrite()':
Write.cpp:516: error: invalid initialization of reference of type 'const volatile bool&' from expression of type 'volatile bool'
../../src/common/Assert.h:27: error: in passing argument 1 of `void unused(const T&) [with T = volatile bool]'
make[1]: *** [ARCH.cygwin/release/Write.o] Error 1
L'argomento inutilizzato è una variabile membro dichiarata come:
volatile bool readWriteActivated;
Si tratta di un bug del compilatore o di un bug nel mio codice?
Ecco il caso di test minimo:
template<typename T>
void unused(T const &) { }
int main() {
volatile bool x = false;
unused(!x); // type of "!x" is bool
}
Soluzione 3
Si tratta di un bug del compilatore e non ci sono arounds di lavoro note:
http://gcc.gnu.org/bugzilla/show_bug.cgi ? id = 42655
Si è risolto in v4.4.
Altri suggerimenti
Il modo attuale di voi che indica in realtà non utilizzare un parametro non sta dando un nome:
int f(int a, float) {
return a*2;
}
compilerà ovunque con tutte le avvertenze accesi, senza avvertimento circa il galleggiante inutilizzato. Anche se l'argomento non ha un nome nel prototipo (ad esempio int f(int a, float f);
), ancora non si lamenterà.
Non sono sicuro al 100% che questo è portatile, ma questo è il linguaggio che ho di solito usato per sopprimere avvertimenti circa le variabili non utilizzate. Il contesto: ecco un gestore di segnale che viene utilizzato solo per la cattura e SIGINT
SIGTERM
, quindi se la funzione è sempre chiamata so che è tempo per il programma per uscire.
volatile bool app_killed = false;
int signal_handler(int signum)
{
(void)signum; // this suppresses the warnings
app_killed = true;
}
Io tendo a non gradire ingombrano l'elenco dei parametri con __attribute__((unused))
, dal momento che il trucco getto a vuoto funziona senza ricorrere alle macro per Visual C ++.
In GCC, è possibile definire una macro come segue:
#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif
I parametri contrassegnati con questa macro consente di eliminare l'avvertimento emette GCC inutilizzati (e rinomina il parametro con un prefisso di UNUSED_
). Per Visual Studio, è possibile eliminare gli avvisi con una direttiva #pragma
.
La risposta proposta da haavee (modificata da ur) è quella che utilizzerei normalmente:
int f(int a, float /*epsilon*/) {
return a*2;
}
Il vero problema accade quando la discussione è A volte ma non sempre utilizzato nel metodo, ad esempio:
int f(int a, float epsilon) {
#ifdef LOGGING_ENABLED
LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
return a*2;
}
Ora, non posso commentare il nome del parametro epsilon perché ciò interromperebbe la mia creazione di registrazione (non voglio inserire un altro #ifdef nell'elenco degli argomenti perché ciò rende il codice molto più difficile da leggere).
Quindi penso che la soluzione migliore sarebbe quella di utilizzare il suggerimento di Tom:
int f(int a, float epsilon) {
(void) epsilon; // suppress compiler warning for possibly unused arg
#ifdef LOGGING_ENABLED
LOG("f: a = %d, epsilon = %f\n", a, epsilon);
#endif
return a*2;
}
La mia unica preoccupazione sarebbe che alcuni compilatori potrebbero avvertire del "(vuoto) epsilon;" Dichiarazione, ad esAvviso "l'istruzione non ha alcun effetto" o qualcosa del genere - immagino che dovrò semplicemente testare su tutti i compilatori che probabilmente utilizzerò...