c++ - 初始化列表中积分提升的规则是什么?这是 GCC 还是 C++ 限制中的误报警告?

标签 c++ c++11 gcc gcc-warning uniform-initialization

在下面的代码中,我们基本上以 4 种不同的方式将相同的值分配给 4 个 unsigned char 变量 - 但其中一种使用初始化列表会发出警告:

警告:将“~(int)a”从“int”缩小转换为“unsigned char”[-Wnarrowing]

#include <iostream>
#include <vector>

int main() {
    unsigned char a = 0b10101010u;      

    unsigned char b = ~a;      
    
    unsigned char c(~a);

    auto test = std::vector<unsigned char>{};
    test.emplace_back(~a);

    auto test2 = std::vector<unsigned char>{~a}; // THIS IS THE LINE GCC COMPLAINS ABOUT

    std::cout << std::hex 
        << size_t(b) << std::endl
        << size_t(c) << std::endl
        << size_t(test[0]) << std::endl
        << size_t(test2[0]) << std::endl;

    return 0;
}

有人能解释一下为什么吗? 这是 GCC 中的错误吗?语言限制?

您可以在这里使用代码:) https://godbolt.org/z/To5ezrecc

最佳答案

警告是正确的。在列表初始化(即带大括号)中,缩小转换的格式不正确,在 std::initializer_list 的元素初始化中也是如此。 。 GCC 在这里相当宽松,因为它产生警告而不是硬错误(例如 Clang 就是这样)。

~a积分促销适用于a 。在这种情况下a晋升为int ,因为它可以表示 unsigned char 的所有值.

因此~a还有类型int并且因为它也不是常量表达式,因此需要转换为 unsigned char对于std::initializer_list<unsigned char>构造函数参数正在缩小。

如果您确实打算显式进行缩小转换:

auto test2 = std::vector<unsigned char>{static_cast<unsigned char>(~a)};

这同样适用于使用列表初始化(大括号)的其他初始化方法:

unsigned char d{~a};
unsigned char e = {~a};

两者的格式都不正确。

关于c++ - 初始化列表中积分提升的规则是什么?这是 GCC 还是 C++ 限制中的误报警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71337225/

相关文章:

optimization - 如何强制 GCC 编译未使用的函数?

c - 如何使用共享库中的方法

c++ - 当特征相同时,如何在为引用和非引用类型编写特征时减少重复

android - 如何确定性地使用 std::this_thread::yield() ?

c++ - std::set 具有多个排序选项

c++ - 如何从 type_info 获取模板参数的类型

C++:如何使用静态常量变量指定数组长度?

c++ - 如何使用安装在 macports 中的 gcc?

c++ - 带有 g++ 5.4.0 的 asan 无法在 travis CI 上运行

c++ - 如何在 Linux 中将子进程 stdout/err) 设置为父进程