【问题标题】:Narrowing from literal doesn't cause warning从字面缩小不会引起警告
【发布时间】:2016-09-13 06:15:48
【问题描述】:

int a = 0; short b{a}; short c{0};

编译器对short b{a} 发出警告。我可以理解这一点,因为int 被缩小为short

但是,它没有向short c{0} 发出警告,这对我来说很奇怪。我记得对于文字整数,0 的类型至少应该是int。所以从int 缩小到short 正在这里发生。为什么编译器不给出警告?

【问题讨论】:

    标签: c++ initialization language-lawyer list-initialization narrowing


    【解决方案1】:

    对于short c{0};,不会出现narrowing conversion。因为0 是一个常量表达式,可以完全存储在short 中。

    (强调我的)

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

    • ...

    • 从整数或无作用域枚举类型转换为不能表示原始所有值的整数类型,除非 source 是一个常量表达式,其值可以完全存储在目标类型中

    标准中的相关解释和示例,$8.6.4/7 List-initialization [dcl.init.list]

    (强调我的)

    窄化转换是隐式转换

    • ...

    • 从整数类型或无作用域枚举类型到不能表示原始类型所有值的整数类型,除了 其中源是一个常量表达式,其值在积分后 促销将适合目标类型

    [ 注意:如上所述,此类转换在 列表初始化中的顶级。 — 尾注] [ 示例:

    // ...
    const int z = 99;
    // ...
    char c4{z};               // OK: no narrowing needed
    unsigned char uc1 = {5};  // OK: no narrowing needed
    // ...
    float f2 { 7 };           // OK: 7 can be exactly represented as a float
    // ...
    

    —结束示例]

    【讨论】:

    • 你觉得“积分后促销”没必要吗?
    • @FunkyBaby 我认为这只是技术上的意思,常量首先会被整数提升,然后会检查提升的值是否适合目标类型。
    猜你喜欢
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 2018-08-23
    相关资源
    最近更新 更多