我的g ++使用vector <weak_ptr> erase()方法生成奇怪的警告

时间:2017-05-24 11:13:07

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

我有以下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时,它会编译而没有任何警告。当我保持标志-O2并取消注释main()中的代码时,它也会编译而没有任何警告。 Clang编译器也不会报告任何警告。

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

我的错误或错误是由编译器引起的警告吗?

1 个答案:

答案 0 :(得分:3)

很可能是gcc 5.4的怪癖。一旦你进入gcc 6.1,它就会消失,我不会再看到它在任何更新的版本中再次出现。

gcc 5.4(警告)

gcc 6.1(无警告)

特别诅咒Clang没有重现这种行为。

应该注意的是,根据doc强调我的

,这种行为并不是一个错误。
  

如果所涉及的变量的值实际上发生溢出,那么假定未发生签名溢出的优化是完全安全的。因此,此警告很容易产生误报:警告代码实际上不是问题。

您使用%s会更有可能,因为这是自己免责声明带来的最高警告级别:

  

此警告级别会产生大量误报

我的建议是升级你的编译器或接受gcc 5.4会在这里给你一个误报。