2011-09-14 24 views
14

boost::mutex::scoped_lock to poręczne opakowanie RAII do blokowania muteksu. Używam podobnej techniki do czegoś innego: wrapper RAII wokół pytania o interfejs danych w celu odłączenia/ponownego podłączenia do urządzenia szeregowego.W jaki sposób scoped_lock unika emitowania ostrzeżenia "nieużywane zmienne"?

Co nie mogę dowiedzieć się, chociaż, dlaczego w kodzie poniżej tylko mojego obiektu mst — którego instancji i niszczenia mają skutki uboczne — przyczyny g++ do emitowania „niewykorzystaną zmienną” Ostrzeżenie błąd podczas l zarządza milczeć.

Czy wiesz? Czy możesz mi powiedzieć?

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

To trochę zbędne, aby zakończyć pytanie: "Czy wiesz, czy możesz mi powiedzieć?". : p – wilhelmtell

+2

@wilhelmtell: Tylko jeden z nich jest zbędny; oba są _stylish_;) –

+0

@ Tomalak Tylko jedna niezwiązana rzecz: Nie chciałbym zobaczyć zmiennej o nazwie 'l' w prawdziwym kodzie :) –

Odpowiedz

6

Należy zauważyć, że pytanie zmieniło się od czasu napisania innych odpowiedzi.

Prawdopodobnie powodem, dla którego g ++ nie ostrzega w bieżącej formie, jest to, że mst jest odniesieniem, a konstruowanie i niszczenie odniesienia nie ma skutków ubocznych. To prawda, że ​​tutaj odniesienie przedłuża czas życia tymczasowego, który ma efekty w swoim konstruktorze i destruktorze, ale najwyraźniej g ++ nie zdaje sobie sprawy, że robi różnicę.

+0

Tak, wydaje się tak. :(Szkoda, że ​​nie ma tu nic bardziej konkretnego (nie jest tak, jakbym mógł oczekiwać, że to zachowanie zostanie udokumentowane), ale zgadzam się z twoją odpowiedzią: –

+1

+1, najbardziej prawdopodobne wyjaśnienie Warto zauważyć, że analiza statyczna jest raczej słabe w kompilatorach i dlatego pojawiają się takie ostrzeżenia – sharptooth

+2

+1: Kiedy kompilator przetwarza tymczasowe powiązanie z odniesieniem do const, wstrzykuje nienazwaną zmienną lokalną, a następnie łączy ją z odnośnikiem. Do czasu, gdy wykona analizę statyczną prawdopodobnie widzi kod podobny do 'type __internal; type const & r = __internal;' i znajduje odniesienie * nieużywane * –

0

Podejrzewam, że powodem jest to, że klasa ma trywialną destruktora i że g ++ ostrzega tylko o zmiennych nieużywanych jeśli destruktor jest trywialne. Wywołanie niezbyt trywialnego destruktora to "użycie" .

+0

Przepraszamy, pytanie edytowane. Nienawidzę, kiedy ludzie to robią, ale było coś, czego nie brałem pod uwagę. Jak widać, nie jest to jedyny czynnik. –

+0

@Tomalak: Więc zredagowałeś Q i wznowiłeś odpowiedź wysłaną, by odebrać oryginalną Q? Czy to jakiś troll? –

+0

@Als: Czy masz teraz magiczną umiejętność "zobacz, kto rzuca które głosy"? Jeśli tak, to okłamuje cię ...Nie scharakteryzowałem, ale ktokolwiek zrobił to prawdopodobnie, ponieważ odpowiedź nie odpowiada na pytanie. Tak, wiem, że to tylko dlatego, że zmieniłem pytanie, ale James może teraz usunąć swoją odpowiedź, a wtedy wszystko jest równe. :) –

1

Jeśli moja pamięć służy mi dobrze, g ++ ma niefortunny nawyk wysyłania błędów unused variable w różny sposób w zależności od ustawień optymalizacji, ponieważ wykrywanie działa na poziomie optymalizatora.

Oznacza to, że kod jest zoptymalizowany w formie SSA, a jeśli optymalizator wykryje, że zmienna, po optymalizacji, jest nieużywana, to może wysłać ostrzeżenie (zdecydowanie wolę analizę Clang dla tego ...).

Dlatego prawdopodobnie chodzi o wykrycie, co robi destruktor. Zastanawiam się, czy zachodzi konserwatywne podejście, gdy definicja destruktora jest w trybie offline, domyśliłbym się, że to równa się wywołanie funkcji i że this kwalifikuje się jako użycie tej zmiennej.

Powiązane problemy