【问题标题】:Is g++ falsely throwing -Wnarrowing?g++ 是否错误地抛出 -Wnarrowing?
【发布时间】:2020-03-06 03:42:05
【问题描述】:

这是在 C++14 模式下运行的 GCC 7.4:

        size_t i = 8;
        std::string strIndent { i, ' ' };

看起来不错,但我收到了警告:

AnalyticsDBI.cpp:538:48: warning: narrowing conversion of ‘i’ from ‘size_t {aka long unsigned int}’ to ‘char’ inside { } [-Wnarrowing]
                 std::string strIndent { i, ' ' };

这是一个编译器错误?我不明白编译器如何选择错误的重载。应该是构造函数2,如图here

【问题讨论】:

    标签: c++ c++14 gcc-warning type-narrowing


    【解决方案1】:

    使用 clang 编译表明它正在尝试调用 initializer_list<char> 构造函数,其中 size_t -> char 是一个缩小转换:

    narrowing.cpp:5:26: error: non-constant-expression cannot be narrowed from type 'size_t' (aka 'unsigned long') to 'char' in initializer list [-Wc++11-narrowing]
            std::string strIndent { i, ' ' };
                                    ^
    narrowing.cpp:5:26: note: insert an explicit cast to silence this issue
            std::string strIndent { i, ' ' };
                                    ^
                                    static_cast<char>( )
    1 error generated.
    

    使用 () 代替将调用你想要的构造函数:

     std::string strIndent(i, ' ');
    

    【讨论】:

      【解决方案2】:

      使用大括号更喜欢列表构造函数(此处采用std::initializer_list&lt;char&gt;,cppreference 上的数字9)。在这个构造函数中,元素是char,所以是一个窄化转换。如果您使用-pedantic-errors 编译,GCC 将为此给出一个实际错误,而不仅仅是一个警告;这不是一个符合标准的程序,因为在大括号初始化中不允许缩小转换。

      【讨论】:

      • 如果我想要这个构造函数,我是否必须使用括号?
      • @ThomasMcLeod,是的,在使用大括号调用标准容器的非列表构造函数时,遇到这样的陷阱并不少见。 (而且你会成为许多人中的一员,称这种情况并不理想。)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 2019-01-02
      • 2021-05-01
      相关资源
      最近更新 更多