【问题标题】:My g++ generates weird warning with vector<weak_ptr> erase() method我的 g++ 使用 vector<weak_ptr> erase() 方法生成奇怪的警告
【发布时间】:2017-10-24 16:47:29
【问题描述】:

我有以下 C++ 代码:

#include <memory>
#include <vector>
#include <string>
#include <unordered_map>

void erase_from_vector(std::vector<std::weak_ptr<int>> &mvec) {
    for (auto mvec_it = mvec.begin(); mvec_it != mvec.end(); )
        mvec_it = mvec.erase(mvec_it);
}

int main(void) {
#if 0
    std::vector<std::weak_ptr<int>> mvec;
    for (auto mvec_it = mvec.begin(); mvec_it != mvec.end(); )
        mvec_it = mvec.erase(mvec_it);
#endif
}

当我以这种方式编译时,GCC 会产生警告:

ppk@fif-cloud-dev:~$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

ppk@fif-cloud-dev:~$ g++ -fstrict-overflow -Wstrict-overflow=5 -O2 -std=c++14  warn1.cc
warn1.cc: In function ‘void erase_from_vector(std::vector<std::weak_ptr<int> >&)’:
warn1.cc:6:6: warning: assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 [-Wstrict-overflow]
 void erase_from_vector(std::vector<std::weak_ptr<int>> &mvec) {
      ^

但是当我将 -O2 标志更改为 -O1 时,它编译时没有任何警告。当我在 main() 中保留标志 -O2 和取消注释代码时,它也会在没有任何警告的情况下编译。 Clang 编译器也不报告任何警告。

我想这个警告来自 std::weak_ptr 析构函数,其中计数器递减但不知道为什么它出现在我的代码中。

这个警告是我的错误还是编译器出错引起的?

【问题讨论】:

  • 为什么很多人将警告误解为错误?警告不是告诉你有任何错误,它只是告诉你它假设代码是正确的,这几乎不可能是错误的。好吧,这是一个相当无用的警告,它可能会在未来的版本中被删除,大多数(全部?)Wstrict-overflow...
  • 因为导致一些警告可能很严重并且难以调试运行时错误。有时,花更多时间分析警告比在将来更正此类错误上花费更多时间更好。尤其是当您创建具有关键可靠性/安全性要求的软件时。

标签: c++ c++11 gcc gcc-warning


【解决方案1】:

很可能是 gcc 5.4 的一个怪癖。一到 gcc 6.1,它就消失了,而且我看不到它在以后的任何版本中再次出现。

gcc 5.4(警告)

gcc 6.1(无警告)

Clang 不会重现这种行为尤其令人遗憾。

应该注意,根据doc强调我的),这种行为并不完全是一个错误

如果所涉及的变量的值使得溢出实际上永远不会发生,则假设不会发生有符号溢出的优化是完全安全的。因此此警告很容易给出误报:关于实际上不是问题的代码的警告。

您使用-Wstrict-overflow=5 的可能性更大,因为这是带有其自己的免责声明的最高警告级别:

此警告级别会导致大量误报

我的建议是要么升级你的编译器,要么接受 gcc 5.4 会给你一个误报。

【讨论】:

  • 或者不要启用记录在案的警告会产生误报。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-26
  • 2012-03-04
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多