【问题标题】:Inconsistent warning "conversion from 'const unsigned char' to 'const float' requires a narrowing conversion"不一致的警告“从 'const unsigned char' 到 'const float' 的转换需要缩小转换”
【发布时间】:2018-10-05 08:56:30
【问题描述】:

Visual C++ 2017 和 gcc 5.4 在此代码 sn-p 中为 Line B 生成 conversion from 'const unsigned char' to 'const float' requires a narrowing conversion 警告,但不为 Line A 生成警告:

#include <iostream>

int main() {
    const unsigned char p = 13;
    const float         q = p;  // Line A

    std::cout << q << '\n';

    const unsigned char c[3] = {0, 1, 255};
    const float         f[3] = {c[2], c[0], c[1]};  // Line B

    for (auto x:f)
        std::cout << x << '\n';
}

这个警告有效吗?为什么Line B 的处理方式与Line A 不同?

【问题讨论】:

    标签: c++ c++11 gcc visual-c++ gcc-warning


    【解决方案1】:

    警告有效,从C++11开始narrowing conversionsaggregate initialization中被禁止;但没有应用在copy initialization(和以前一样)。

    如果初始化子句是表达式,则允许按照复制初始化, except if they are narrowing (as in list-initialization) (since C++11).进行隐式转换

    在 C++11 之前,聚合初始化中允许缩小转换,但不再允许。

    list-initialization 通过以下方式限制允许的隐式转换 禁止:

    • 从整数类型转换为浮点类型,除非源是可以存储其值的常量表达式 完全符合目标类型

    顺便说一句:c[0]c[1]c[2]not constant expressions;您可以将数组声明为constexpr,即constexpr unsigned char c[3] = {0, 1, 255};。然后应用异常,Line B 也可以正常工作。

    【讨论】:

    • 但我的示例中的初始化列表仅包含 constant expression whose value can be stored exactly in the target type!
    • @PaulJurczak AFAIK c[0]c[1]c[2] 不是常量表达式。
    • @songyuanyao:警告不会使编译器无法投诉。反过来是不正确的。当标准要求诊断时,编译器必须至少发出警告。
    • @songyuanyao:编译器会给出过多使用字母 E 的警告,但仍然是合规的。该标准只要求编译器为格式良好的代码生成正确的二进制文件。
    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-25
    • 2011-10-23
    相关资源
    最近更新 更多