Visual C ++ 2017和gcc 5.4在此代码段中针对conversion from 'const unsigned char' to 'const float' requires a narrowing conversion
生成Line B
警告,但不针对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
不同?
答案 0 :(得分:5)
警告有效,来自C ++ 11 narrowing conversions中禁止aggregate initialization;但未在copy initialization中应用(如前所述)。
如果initializer子句是表达式,则根据copy-initialization
允许隐式转换, except if they are narrowing (as in list-initialization) (since C++11).
在C ++ 11之前,在聚合初始化中允许缩小转换,但不再允许它们。
和
list-initialization限制允许的隐式转换 禁止以下内容:
- 从整数类型转换为浮点类型,除非源是可以存储其值的常量表达式 完全在目标类型
BTW:c[0]
,c[1]
和c[2]
是not constant expressions;您可以将数组声明为constexpr
,即constexpr unsigned char c[3] = {0, 1, 255};
。然后应用异常,Line B也可以正常工作。