为什么没有gcc/g++对未使用的临时文件发出警告?
考虑以下代码:(
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。 目标是保护订阅者
容器。
但确实很难注意到这些锁实际上只是临时的(仔细看看,没有为它们指定名称)。 因此,当临时对象被破坏时,互斥锁上的锁将立即释放,即代码不是线程安全的。 我希望在这种情况下会出现编译器警告。类似“临时未使用”之类的东西。
更糟糕的是,cppcheck 也不会识别这个错误。 (cppcheck:ac/c++代码分析工具 http://sourceforge.net/ apps/mediawiki/cppcheck/index.php?title=Main_Page)
Gcc 对未使用的变量发出警告。这里的临时是一个未使用的变量,绝对是程序员不注意的结果。 那么,为什么在这种情况下没有警告呢?也许发现这种情况太复杂了?
Consider the following code :
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);
}
}
(This is an implementation of an observer pattern as described in GoF.)
The user intervention here was to protect the attach() and the notify() from simultaneous running, hence the boost::unique_lock.
The goal was to protect the subscribers
container.
But it is indeed extremely hard to notice that the locks are in fact just temporaries (take a closer look, there are no names assigned for them).
So the lock on the mutex will be released immediately, when the temporary is destructed, i.e. the code is not thread safe.
I would expect in situations like this a compiler warning. Something like "Unused temporary".
Even worse, cppcheck wouldn't recognize this mistake either.
(cppcheck: a c/c++ code analysis tool http://sourceforge.net/apps/mediawiki/cppcheck/index.php?title=Main_Page)
Gcc issues warnings on unused variables. The temporary here is an unused variable, and definitely the result of the programmer's inattention.
So, why there are no warnings in cases like this? Maybe it is too complicated to discover such situations?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
编译器不会发出警告,因为您很可能正在更新构造函数内的某些
static-member / global
变量(这是有效且有意义的)。例如:现在,当您简单地调用临时:
如果没有发生此类更新,编译器将不会深入
A
的构造函数并检查是否发生了有用的事情。它始终假设是一个有效的场景。有很多这样的案例可以指出与临时相关。Compiler doesn't issue a warning, because it's quite possible that you might be updating some
static-member / global
variable inside the constructor (which is valid and meaningful). e.g.:Now when you simply invoke a temporary:
In case if such update is not happening, compiler will not dig into the constructor of
A
and check if something useful is happening. It always assumes to be a valid scenario. There are many such cases can be pointed out related to temporaries.请注意,您建议的警告也会针对每个
it++;
发出,这在许多 for 循环中都可以找到。iammilind 已经提到过,有时是故意创建并立即销毁临时值:当存在副作用时。
在模板元编程中,人们可能会创建和销毁临时对象,以防用户提供带有副作用的类。当使用一个没有副作用的简单类来实例化模板时,警告将出现在模板代码的深处。
因此,您提出的警告将有许多误报。在虚假警告中很难找到真正的警告。
因此,我希望编译器供应商已经决定将他们的时间花在其他地方更好。
Note that your proposed warning will also be issued for every
it++;
, which is found in many for loops.iammilind has already mentioned that sometimes it is by intention to create and immediatly destroy the temp: when there are side-effects.
And in template meta programming, one might create and destroy a temporary, just in case the user supplies a class with side-effects. When a simple class, without side-effects, is used to instantiate the template, warnings will appear deep down in the template code.
Therefor, your proposed warning will have many false positives. It will be hard to find the genuine warnings among the spurious ones.
So I expect that compiler vendors have decided that their time is better spent elsewhere.
嗯..我不确定,但是普通的 c++ 也不能防止这种情况发生吗?
使用 DJGPP 编译时,我收到此编译器警告:
如果我取消注释“lock”并添加互斥变量,则编译正常。
所以如果你的“mtx”变量是一个指针。如果您更改它并将其作为“&mtx”传递,会发生什么。
hmm.. I am not sure but can't this be protected against with normal c++ also?
I get this compiler warning when compiling with DJGPP:
It compiles fine if I uncomment "lock" and add a mutex variable.
So if your "mtx" variable is a pointer. What happens if you change it and pass it as "&mtx" instead.