我的g++;使用矢量生成奇怪的警告<;弱ptr>;erase()方法 我有以下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 } #包括 #包括 #包括 #包括 从_向量中删除_无效(标准::向量和mvec){ for(auto mvec_it=mvec.begin();mvec_it!=mvec.end();) mvec_it=mvec.erase(mvec_it); } 内部主(空){ #如果0 std::载体mvec; for(auto mvec_it=mvec.begin();mvec_it!=mvec.end();) mvec_it=mvec.erase(mvec_it); #恩迪夫 }

我的g++;使用矢量生成奇怪的警告<;弱ptr>;erase()方法 我有以下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 } #包括 #包括 #包括 #包括 从_向量中删除_无效(标准::向量和mvec){ for(auto mvec_it=mvec.begin();mvec_it!=mvec.end();) mvec_it=mvec.erase(mvec_it); } 内部主(空){ #如果0 std::载体mvec; for(auto mvec_it=mvec.begin();mvec_it!=mvec.end();) mvec_it=mvec.erase(mvec_it); #恩迪夫 },c++,c++11,gcc,gcc-warning,C++,C++11,Gcc,Gcc Warning,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

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) {
      ^
ppk@fif-云开发人员:~$g++--版本
g++(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609
ppk@fif-云开发:~$g++-fstrict overflow-Wstrict overflow=5-O2-std=c++14 warn1.cc
warn1.cc:在函数“void erase_from_vector(std::vector&)”中:
警告1.cc:6:6:警告:假设在将X+-C1 cmp C2更改为X cmp C2-+C1[-Wstrict overflow]时未发生有符号溢出
从_向量中删除_无效(标准::向量和mvec){
^
但是当我将-O2标志更改为-O1时,它编译时没有任何警告。当我在main()中保留标志-O2并取消注释代码时,它也编译时没有任何警告。Clang编译器也不报告任何警告

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


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

很可能是gcc 5.4的一个怪癖。当您访问gcc 6.1时,它就消失了,我看不到它在任何更高版本中再次出现

(警告)

(无警告)

尤其令人痛心的是,叮当声没有再现这种行为

应该注意的是,根据(强调矿山)的说法,这种行为并不完全是一个bug

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

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

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


我的建议是要么升级编译器,要么接受gcc 5.4将给您带来的误报。

为什么这么多人将警告误解为错误?警告并不是告诉您有任何错误,它只是告诉您它假设代码是正确的,这几乎不会错。好吧,这是一个相当有用的方法它可能会在将来的版本中被删除,大多数(全部?)Wstrict溢出的原因…因为某些警告可能严重且难以调试运行时错误。有时,花更多时间分析警告比花更多时间纠正此类错误更好。尤其是当您创建具有关键可靠性/安全性要求的软件时。或者不启用记录到p的警告产生假阳性。