【发布时间】:2020-05-16 13:40:50
【问题描述】:
为什么在使用-O2 和-DNDEBUG 编译时,gcc 会给我带有过滤范围的deque::insert 可能未初始化的警告
#include <deque>
#include <vector>
#include <boost/range/adaptor/filtered.hpp>
auto foo(){
std::deque<int> d{3,4};
std::vector<int> v{0,2};
auto b = 1;
using boost::adaptors::filtered;
auto r = v | filtered([&b](auto i){return i>b;});
d.insert(std::end(d),r.begin(),r.end());
return d;
}
编译器 gcc 9.2,标志 -std=c++2a -O2 -Wall -Werror -DNDEBUG
这是警告:
<source>: In member function 'void std::deque<_Tp, <source>: In member function 'void std::deque<_Tp, _Alloc>::_M_insert_aux(std::deque<_Tp, _Alloc>::iterator, _ForwardIterator, _ForwardIterator, std::deque<_Tp, _Alloc>::size_type) [with _ForwardIterator = boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(auto:1)>, bool>, __gnu_cxx::__normal_iterator<int*, std::vector<int> > >; _Tp = int; _Alloc = std::allocator<int>]':
<source>:10:48: error: '*((void*)& __mid +16)' may be used uninitialized in this function [-Werror=maybe-uninitialized]
10 | auto r = v | filtered([&b](auto i){return i>b;});
| ~^~
In file included from /opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/deque:69,
from <source>:1:
/opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/bits/deque.tcc:793:24: note: '*((void*)& __mid +16)' was declared here
793 | _ForwardIterator __mid = __first;
| ^~~~~
<source>:10:48: error: '*((void*)& __mid +16)' may be used uninitialized in this function [-Werror=maybe-uninitialized]
10 | auto r = v | filtered([&b](auto i){return i>b;});
|
如果b被值捕获,则警告消失。
【问题讨论】:
-
只是一个编译器错误。请注意,gcc 8 不再发出警告。
-
+1 表示编译器错误。如果您将 lambda 更改为仅通过引用
[&]捕获所有内容,则错误也会消失,因此对于命名捕获的初始化状态会感到困惑...... -
请注意,在此警告中,“未初始化”也可以表示“在其销毁之后”。
-
这个警告一直(仍然)非常脆弱。特别是,它经常触发编译器没有注意到的死代码,死代码很容易是编译器本身通过内联、展开等产生的东西。