为什么没有未使用的临时工具的gcc / g ++警告?

时间:2011-06-29 09:22:16

标签: c++ thread-safety gcc-warning temporaries

请考虑以下代码:

void ListenerImpl::attach(boost::shared_ptr<ISubscriber> subscriber)
{
    boost::unique_lock<boost::mutex>(mtx);
    subscribers.push_back(subscriber);
}

void ListenerImpl::notify(MsgPtr msg)
{
    boost::unique_lock<boost::mutex>(mtx);

    //notify all subscribers
    BOOST_FOREACH(boost::shared_ptr<ISubscriber> subscriber, subscribers){
        subscriber->update(msg);
    }

}

(这是GoF中描述的观察者模式的实现。) 这里的用户干预是保护attach()和notify()不同时运行,因此boost :: unique_lock。 目标是保护subscribers容器。

但确实很难注意到锁实际上只是暂时的(仔细看看,没有为它们分配名称)。 因此,当临时被破坏时,互斥锁上的锁定将被立即释放,即代码不是线程安全的。 我希望在这种情况下编译器警告。类似“未使用的临时”的东西。

更糟糕的是,cppcheck也不会认识到这个错误。 (cppcheck:一个c / c ++代码分析工具http://sourceforge.net/apps/mediawiki/cppcheck/index.php?title=Main_Page

Gcc对未使用的变量发出警告。这里的临时变量是一个未使用的变量,绝对是程序员注意力不集中的结果。 那么,为什么在这种情况下没有警告呢?发现这种情况可能太复杂了吗?

3 个答案:

答案 0 :(得分:8)

编译器不会发出警告,因为很可能您在构造函数中更新了一些static-member / global变量(这是有效且有意义的)。 e.g:

struct A
{
  static int count;
  A () { count ++; }
};

现在当你只是调用临时的时候:

A();

如果没有发生这样的更新,编译器将不会深入研究A的构造函数,并检查是否发生了有用的更新。它总是假设是一个有效的场景。有很多这样的案例可以指出与临时工有关。

答案 1 :(得分:0)

请注意,您的建议警告也会针对每个it++;发出,这可以在许多for循环中找到。

iammilind已经提到过,有时它会产生并立即摧毁温度:当有副作用时。

在模板元编程中,可以创建并销毁临时文件,以防用户提供带副作用的类。当使用没有副作用的简单类来实例化模板时,警告将显示在模板代码的深处。

因此,您提出的警告将有许多误报。在虚假的警告中很难找到真正的警告。

所以我希望编译器供应商已经决定将时间花在其他地方更好。

答案 2 :(得分:0)

嗯..我不确定但是这也不能用正常的c ++来保护它吗?

class Mutex;
class Lock {
    Lock(Mutex *mutex);
};

int main() {
    Lock /* lock */ (&mtx);
    return 0;
}

在使用DJGPP编译时,我收到此编译器警告:

C:\df>gxx -c a.cpp
a.cpp: In function 'int main()':
a.cpp:8:30: error: 'mtx' declared as reference but not initialized

如果我取消注释“lock”并添加互斥变量,它就会编译好。

所以如果你的“mtx”变量是一个指针。如果您更改它并将其作为“&amp; mtx”传递,会发生什么。