2011-09-14 7 views
14

boost::mutex::scoped_lock è un pratico wrapper RAII che blocca un mutex. Uso una tecnica simile per qualcos'altro: un wrapper RAII che richiede un'interfaccia dati per staccare/reinserire su un dispositivo seriale.In che modo scoped_lock non emette un avviso di "variabile non utilizzata"?

Quello che non riesco a capire, però, è il motivo per cui nel seguente codice solo il mio oggetto mst — cui istanziazione e distruzione hanno effetti collaterali — cause g++ per emettere un "variabile non utilizzata" Errore di avvertimento, mentre l gestisce rimanere in silenzio.

Lo sai? Puoi dirmi?

[[email protected] ~]$ cat test.cpp 
#include <boost/shared_ptr.hpp> 
#include <boost/thread/mutex.hpp> 
#include <iostream> 

struct MyScopedThing; 
struct MyWorkerObject { 
    void a() { std::cout << "a"; } 
    void b() { std::cout << "b"; } 

    boost::shared_ptr<MyScopedThing> getScopedThing(); 
}; 

struct MyScopedThing { 
    MyScopedThing(MyWorkerObject& w) : w(w) { 
     w.a(); 
    } 
    ~MyScopedThing() { 
     w.b(); 
    } 

    MyWorkerObject& w; 
}; 

boost::shared_ptr<MyScopedThing> MyWorkerObject::getScopedThing() { 
    return boost::shared_ptr<MyScopedThing>(new MyScopedThing(*this)); 
} 

int main() { 
    boost::mutex m; 
    boost::mutex::scoped_lock l(m); 

    MyWorkerObject w; 
    const boost::shared_ptr<MyScopedThing>& mst = w.getScopedThing(); 
} 


[[email protected] ~]$ g++ test.cpp -o test -lboost_thread -Wall 
test.cpp: In function ‘int main()’: 
test.cpp:33: warning: unused variable ‘mst’ 

[[email protected] ~]$ ./test 
ab[[email protected] ~]$ g++ -v 2>&1 | grep version 
gcc version 4.4.5 20110214 (Red Hat 4.4.5-6) (GCC) 
+2

È un po 'ridondante porre fine a una domanda con "Lo sai? Puoi dirmelo?". : p – wilhelmtell

+2

@wilhelmtell: solo uno di questi è ridondante; entrambi sono _stylish_;) –

+0

@Tomalak Solo una cosa non correlata: non mi piacerebbe vedere la variabile denominata 'l' nel codice reale :) –

risposta

6

Si noti che la domanda è cambiata da quando sono state scritte le altre risposte.

Probabilmente la ragione per cui g ++ non avverte nella forma corrente è perché mst è un riferimento e la costruzione e la distruzione di un riferimento non hanno effetti collaterali. È vero che qui il riferimento sta estendendo la durata di un temporaneo, che ha effetti nel suo costruttore e distruttore, ma apparentemente g ++ non si rende conto che fa la differenza.

+0

Sì, sembra così. :(È un peccato che non ci sia nulla di più concreto qui (non è come se potessi aspettarmi che questo comportamento fosse documentato), ma sono d'accordo con la tua risposta: –

+1

+1, la spiegazione più probabile. Vale la pena notare che l'analisi statica è piuttosto debole nei compilatori ed è per questo che si presentano tali avvertimenti – sharptooth

+2

+1: quando il compilatore elabora l'associazione temporanea al riferimento const, inietta una variabile locale senza nome e quindi la lega con il riferimento. probabilmente vede il codice simile a 'type __internal; type const & r = __internal;' e trova il riferimento * inutilizzato * –

0

ho il sospetto che il motivo è che la classe ha un banale distruttore, e che g ++ avverte solo di variabili inutilizzate se il distruttore è banale. Invocare un distruttore non banale è un "uso" .

+0

Spiacente, domanda modificata. Odio quando le persone lo fanno, ma c'era qualcosa che non avevo considerato. Come ora puoi vedere, questo non è l'unico fattore. –

+0

@Tomalak: Quindi hai modificato la Q e hai downvoted una risposta inviata per rispondere alla Q originale? O è un troll? –

+0

@Als: Hai una magia "vedi chi lancia quale voto?" Se è così, ti sta mentendo ...Non ho fatto un downvote, ma chiunque lo abbia fatto probabilmente perché la risposta non risponde alla domanda. Sì, lo so che è solo perché ho cambiato la domanda, ma James è libero di cancellare la sua risposta e quindi è tutto uguale. :) –

1

Se la memoria mi serve correttamente, g ++ ha la sfortunata abitudine di emettere errori unused variable in modo diverso a seconda delle impostazioni di ottimizzazione perché il rilevamento funziona a livello di ottimizzazione.

Ovvero, il codice è ottimizzato in formato SSA e, se l'ottimizzatore rileva che una variabile, dopo l'ottimizzazione, non è utilizzata, potrebbe emettere un avviso (preferisco di gran lunga l'analisi Clang per questo ...).

Quindi è probabilmente una questione di rilevare cosa fa il distruttore. Mi chiedo se è necessario un approccio conservativo ogni volta che la definizione del distruttore è offline, suppongo che equivale a una chiamata di funzione e che lo this si qualifichi come un uso della variabile.

Problemi correlati