Как scoped_lock избегает предупреждения «неиспользуемая переменная»? - PullRequest
15 голосов
/ 14 сентября 2011

boost::mutex::scoped_lock - это удобная оболочка RAII для блокировки мьютекса. Я использую аналогичную технику для чего-то другого: обертка RAII, запрашивающая интерфейс данных для отсоединения / повторного подключения к последовательному устройству.

Однако я не могу понять, почему в приведенном ниже коде только мой объект mst & mdash; чье создание и уничтожение имеют побочные эффекты & mdash; заставляет g++ выдавать ошибку предупреждения «неиспользуемая переменная», тогда как l удается сохранять молчание.

Знаете ли вы? Можете ли вы сказать мне?

[generic@sentinel ~]$ 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();
}


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

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

Ответы [ 3 ]

6 голосов
/ 14 сентября 2011

Обратите внимание, что вопрос изменился с тех пор, как были написаны другие ответы.

Вероятно, причина того, что g ++ не предупреждает в текущей форме, заключается в том, что mst является ссылкой, а создание и удаление ссылки имеетнет побочных эффектов.Это правда, что здесь ссылка продлевает время жизни временного объекта, что оказывает влияние на его конструктор и деструктор, но, очевидно, g ++ не понимает, что это меняет.

1 голос
/ 14 сентября 2011

Если память мне не изменяет, g ++ имеет неудачную привычку выдавать ошибки unused variable по-разному в зависимости от настроек оптимизации, поскольку обнаружение работает на уровне оптимизатора.

То есть код оптимизируется вФорма SSA, и если оптимизатор обнаружит, что переменная после оптимизации не используется, то она может выдать предупреждение (я очень предпочитаю анализ Clang для этого ...).

Поэтому, вероятно, это вопрособнаружение того, что делает деструктор.Интересно, будет ли применяться консервативный подход, когда определение деструктора находится в автономном режиме, я бы предположил, что это приравнивает вызов функции и что this квалифицируется как использование переменной.

0 голосов
/ 14 сентября 2011

Я подозреваю, что причина в том, что ваш класс имеет тривиальное деструктор, и что g ++ только предупреждает о неиспользуемых переменных, если деструктор тривиален. Вызов нетривиального деструктора является «Использовать».

...