2011-09-14 6 views
14

boost::mutex::scoped_lock es una práctica envoltura RAII alrededor del bloqueo de un mutex. Utilizo una técnica similar para otra cosa: una envoltura de RAII alrededor de la cual se pide a una interfaz de datos que se separe o se vuelva a conectar a un dispositivo en serie.¿Cómo evita scoped_lock emitir una advertencia de "variable no utilizada"?

Lo que no puedo entender, sin embargo, es por eso que en el código de abajo solamente mi objetivo mst — cuya ejemplificación y la destrucción tienen efectos secundarios — causas g++ para emitir una "variable sin usar" error de advertencia mientras que gestiona l a guardar silencio.

¿Sabes? ¿Usted pude decirme?

[[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

Es un poco redundante terminar una pregunta con "¿Sabes? ¿Me puedes decir?". : p – wilhelmtell

+2

@wilhelmtell: solo uno de ellos es redundante; ambos son _stylish_;) –

+0

@Tomalak Solo una cosa no relacionada: odiaría ver una variable llamada 'l' en código real :) –

Respuesta

6

Tenga en cuenta que la pregunta ha cambiado desde que se escribieron las otras respuestas.

Probablemente la razón g ++ no advierte en la forma actual es porque mst es una referencia, y la construcción y destrucción de una referencia no tiene efectos secundarios. Es cierto que aquí la referencia está extendiendo la vida útil de un temporal, que tiene efectos en su constructor y destructor, pero aparentemente g ++ no se da cuenta de que hace la diferencia.

+0

Sí, parece que sí. :(Es una lástima que no haya nada más concreto aquí (no es como si pudiera esperar documentar este comportamiento), pero estoy de acuerdo con su respuesta. –

+1

+1, la explicación más probable. Vale la pena señalar que el análisis estático es más bien débil en los compiladores y esta es la razón por la cual surgen tales advertencias. – sharptooth

+2

+1: Cuando el compilador procesa el enlace temporal a la referencia constante, inyecta una variable local sin nombre y luego la vincula con la referencia. Cuando llega el momento de realizar el análisis estático probablemente vea código similar a 'escriba __internal; escriba const & r = __internal;' y encuentre la referencia * no utilizada * –

0

Sospecho que la razón es que su clase tiene un trivial destructor, y que sólo g ++ advierte acerca de las variables utilizadas si el destructor es trivial. Invocar un destructor no trivial es un "uso" de .

+0

Disculpe, la pregunta ha sido editada. Odio cuando la gente hace eso, pero había algo que no había considerado. Como puede ver, este no es el único factor. –

+0

@Tomalak: ¿Así que editó la Q y revocó una respuesta publicada para responder la Q original? ¿O es un troll? –

+0

@ Alles: ¿Ahora tiene una habilidad mágica de "ver quién arroja qué votos"? Si es así, te está mintiendo ...No perdoné, pero quien lo hizo probablemente lo hizo porque la respuesta no responde la pregunta. Sí, sé que eso es solo porque cambié la pregunta, pero James ahora puede borrar su respuesta y todo es igual. :) –

1

Si mi memoria me sirve bien, g ++ tiene la desafortunada costumbre de emitir errores unused variable de manera diferente dependiendo de la configuración de optimización porque la detección funciona en el nivel del optimizador.

Es decir, el código está optimizado en formato SSA, y si el optimizador detecta que una variable, después de la optimización, no se utiliza, puede emitir una advertencia (prefiero el análisis de Clang para esto ...).

Por lo tanto, es probable que se trate de detectar lo que hace el destructor. Me pregunto si se necesita un enfoque conservador cada vez que la definición del destructor está fuera de línea, supongo que esto equivale a una llamada de función y que el this califica como un uso de la variable.

Cuestiones relacionadas