GCC 警告将初始化列表分配到向量中

问题描述 投票:0回答:1

考虑以下 C++ 代码:

#include <cstdint>
#include <vector>

template<typename BaseType>
class InitInt {
public:
    using base_type = BaseType;

private:
    BaseType value_;

public:
    InitInt() : value_(0) {}

    explicit InitInt(BaseType value) : value_(value) {}

    InitInt(
        const InitInt<BaseType>& other)
        : value_(other.get()) {}

    const BaseType& get() const { return value_; }
};

using InitInt16 = InitInt<int16_t>;

class IntInt16PairVector {
public:
    std::vector<std::pair<InitInt16, InitInt16>> m;
};

void f(IntInt16PairVector& v) {
    v.m = {{InitInt16(0), InitInt16(0)}};
}

int main(void) {
    IntInt16PairVector v;

    f(v);
}

当使用带有标志

-O3
-Wall
的 GCC 12.3.0 编译此代码时,它会警告在函数中使用未初始化的值
f()

In copy constructor ‘InitInt<BaseType>::InitInt(const InitInt<BaseType>&) [with BaseType = short int]’,
    inlined from ‘std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = InitInt<short int>; _T2 = InitInt<short int>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/stl_pair.h:195:17,
    inlined from ‘void std::_Construct(_Tp*, _Args&& ...) [with _Tp = pair<InitInt<short int>, InitInt<short int> >; _Args = {const pair<InitInt<short int>, InitInt<short int> >&}]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/stl_construct.h:119:7,
    inlined from ‘_ForwardIterator std::__do_uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const pair<InitInt<short int>, InitInt<short int> >*; _ForwardIterator = pair<InitInt<short int>, InitInt<short int> >*]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/stl_uninitialized.h:120:21,
    inlined from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const std::pair<InitInt<short int>, InitInt<short int> >*; _ForwardIterator = std::pair<InitInt<short int>, InitInt<short int> >*; bool _TrivialValueTypes = false]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/stl_uninitialized.h:137:32,
    inlined from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const pair<InitInt<short int>, InitInt<short int> >*; _ForwardIterator = pair<InitInt<short int>, InitInt<short int> >*]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/stl_uninitialized.h:185:15,
    inlined from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator = const pair<InitInt<short int>, InitInt<short int> >*; _ForwardIterator = pair<InitInt<short int>, InitInt<short int> >*; _Tp = pair<InitInt<short int>, InitInt<short int> >]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/stl_uninitialized.h:372:37,
    inlined from ‘void std::vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const std::pair<InitInt<short int>, InitInt<short int> >*; _Tp = std::pair<InitInt<short int>, InitInt<short int> >; _Alloc = std::allocator<std::pair<InitInt<short int>, InitInt<short int> > >]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/vector.tcc:339:35,
    inlined from ‘std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(std::initializer_list<_Tp>) [with _Tp = std::pair<InitInt<short int>, InitInt<short int> >; _Alloc = std::allocator<std::pair<InitInt<short int>, InitInt<short int> > >]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/stl_vector.h:785:21,
    inlined from ‘void f(IntInt16PairVector&)’ at test.cpp:32:37:
test.cpp:19:11: warning: ‘<anonymous>’ may be used uninitialized [-Wmaybe-uninitialized]
   19 |         : value_(other.get()) {}
      |           ^~~~~~~~~~~~~~~~~~~
test.cpp: In function ‘void f(IntInt16PairVector&)’:
test.cpp:32:44: note: ‘<anonymous>’ declared here
   32 |         v.m = {{InitInt16(0), InitInt16(0)}};
      |                                            ^

我认为此警告是由于使用未初始化的副本将初始值设定项列表分配到向量中造成的。我怎样才能删除这个?

c++ gcc-warning
1个回答
0
投票

警告来自 main 中的

v
,它尚未初始化。为什么 GCC 决定发出警告,我并不是 100% 清楚,但我怀疑,当您提供自己的复制构造函数时,GCC 以某种方式选择假设,您可能会在那里做一些有趣的事情。您有两种选择来消除警告:

  • 您可以通过编写
    v
    来初始化 main 中的
    IntInt16PairVector v{};
    ,注意空大括号。
  • 或者删除自定义复制构造函数。当您进行成员复制时,最好让编译处理它并为您提供默认构造函数。此外,通过提供复制构造函数但不提供复制赋值运算符,您违反了“三规则”。考虑阅读有关编译器何时为您生成默认构造函数的信息。
© www.soinside.com 2019 - 2024. All rights reserved.