C++ 作用域的“U锁”如何避免发出;“未使用变量”;警告

C++ 作用域的“U锁”如何避免发出;“未使用变量”;警告,c++,boost,g++,compiler-warnings,C++,Boost,G++,Compiler Warnings,boost::mutex::scoped_lock是锁定互斥锁的一个方便的RAII包装器。我在其他方面使用了类似的技术:一个RAII包装器,要求数据接口与串行设备分离/重新连接 然而,我不明白的是,为什么在下面的代码中,只有我的对象mst(其实例化和销毁确实有副作用)会导致g++发出“未使用变量”警告错误,而l却保持沉默 你知道吗?你能告诉我吗 [generic@sentinel ~]$ cat test.cpp #include <boost/shared_ptr.hpp> #in

boost::mutex::scoped_lock
是锁定互斥锁的一个方便的RAII包装器。我在其他方面使用了类似的技术:一个RAII包装器,要求数据接口与串行设备分离/重新连接

然而,我不明白的是,为什么在下面的代码中,只有我的对象
mst
(其实例化和销毁确实有副作用)会导致
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)
[generic@sentinel~]$cat test.cpp
#包括
#包括
#包括
结构MyScopedThing;
结构MyWorkerObject{

void a(){std::cout我怀疑原因是您的类有一个微不足道的 析构函数,并且g++仅在以下情况下警告未使用的变量 析构函数是平凡的。调用非平凡析构函数是
“使用”。

如果我的记忆正常,g++有一个不幸的习惯,即根据优化设置发出不同的
未使用变量
错误,因为检测工作在优化器级别

也就是说,代码是以SSA形式优化的,如果优化器在优化后检测到某个变量未使用,那么它可能会发出警告(我更喜欢对此进行叮当分析…)


因此,这可能是一个检测析构函数做什么的问题。我想知道当析构函数的定义离线时,它是否采取保守的方法,我会猜测这等同于一个函数调用,并且
this
符合变量的使用条件。

注意,自从另一个有人写下了脏话


g++没有以当前形式发出警告的原因可能是因为
mst
是一个引用,构造和销毁引用没有副作用。这里引用确实是在延长临时的生存期,这对其构造函数和析构函数有影响,但显然g++没有意识到这会使参考资料。

以“你知道吗?你能告诉我吗?”作为问题的结尾有点多余. :p@wilhelmtell:其中只有一个是多余的;两个都很时髦;@Tomalak只有一件不相关的事:我不想看到名为
l
的变量出现在真实代码中:)@Alexander:我不想看到一个在真实代码中完全不起作用的程序。@Alexander:我不会,我经常用一个字母(或几个字母)来命名短期变量。过长的名字不一定会增加可读性。对不起,问题编辑。我讨厌人们这样做,但有一点我没有考虑。正如你现在看到的,这不是唯一的因素。@Tomalak:所以你编辑了Q,并否决了为回答原始Q而发布的答案?或者是某个巨魔?@Als:你现在有魔法了吗“看谁投哪一票"能力?如果是这样的话,那就是在骗你……我没有投反对票,但不管是谁投了反对票,可能是因为答案没有回答问题。是的,我知道那只是因为我改变了问题,但詹姆斯现在可以自由删除他的答案,然后一切都是平等的。@Tomalak:不,我没有任何魔法能力,因此在结束我的评论&也是
或者它是某个巨魔?
部分。这个查询是因为最近巨魔随机向下投票是一个反复出现的问题,而且,我认为向下投票是非常不道德的,因为答案没有回答发布后编辑过的问题。投票应该反映在任何给定的时间,是否n答案回答了所陈述的问题。如果问题发生了变化,那么这确实是非常不幸的,但它并没有改变事实。是的,似乎是这样。(遗憾的是,这里没有更具体的内容(我不希望这种行为被记录在案),但我同意你的答案。+1,最有可能的解释。值得注意的是,编译器中的静态分析非常弱,这就是为什么会出现这样的警告。+1:当编译器处理对const引用的临时绑定时,它会注入一个未命名的局部变量,然后将其与引用绑定。当它开始执行时在静态分析中,它可能会看到类似于
type\uu internal;type const&r=\uu internal;
的代码,并发现未使用的引用