Как scoped_lock избегает выдавать предупреждение "неиспользуемая переменная"?
boost::mutex::scoped_lock
- удобная обертка RAII вокруг блокировки мьютекса. Я использую подобный метод для чего-то еще: обертка RAII вокруг запроса интерфейса данных отсоединиться от/повторного присоединения к последовательному устройству.
Однако я не могу понять, почему в приведенном ниже коде только мой объект mst
— чьи инстанцирование и разрушение имеют побочные эффекты; вызывает g++
, чтобы испустить ошибку "неиспользуемая переменная", тогда как l
удается сохранить молчание.
Знаете ли вы? Можешь мне сказать?
[[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)
Ответы
Ответ 1
Обратите внимание, что вопрос изменился с тех пор, как были написаны другие ответы.
Вероятно, причина, по которой g++ не предупреждает в текущей форме, заключается в том, что mst
является ссылкой, а построение и уничтожение ссылки не имеет побочных эффектов. Это правда, что здесь ссылка распространяется на время жизни временного, которое имеет эффекты в его конструкторе и деструкторе, но, судя по всему, g++ не понимает, что имеет значение.
Ответ 2
Если моя память мне подходит, g++ имеет неудачную привычку испускать ошибки unused variable
по-разному в зависимости от настроек оптимизации, потому что обнаружение работает на уровне оптимизатора.
То есть, код оптимизирован в форме SSA, и если оптимизатор обнаруживает, что переменная после оптимизации не используется, тогда она может выдавать предупреждение (я предпочитаю анализ Clang для этого...).
Поэтому, вероятно, это вопрос обнаружения того, что делает деструктор. Интересно, берет ли он консервативный подход, когда определение деструктора отключено, я бы предположил, что это приравнивает вызов функции тогда и что this
квалифицируется как использование переменной.
Ответ 3
Я подозреваю, что причина в том, что ваш класс имеет тривиальный
деструктор, а g++ предупреждает о неиспользуемых переменных, если
деструктор тривиален. Вызов нетривиального деструктора - это
"Использовать".