在我的系统上( 4.13.11-1-ARCH,gcc 7.2.0 )char
为signed
。使用char
初始化integer literal
数组时,如下所示:
const char mydata[] = {
0x80
};
我收到以下错误:
error: narrowing conversion of ‘128’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
然而,当我改为const char data = 0x80
时,编译器并不担心任何缩小,尽管它当然发生了。输出为7F
,最高正signed char
值。
为什么编译器在两种情况下都不会同样担心截断?
答案 0 :(得分:5)
这实际上是首选{}
初始化的原因之一:它不允许缩小转换范围。与此相反,旧的初始化方式(如const char data = 0x80
)确实可以缩小转换次数。
答案 1 :(得分:2)
const char c = 0x80
形式的初始化程序是一个比它更老的结构
初始化列表,稍后介绍。因此可以为初始化程序列表定义更严格的规则,而这些规则不适用于“较旧”的初始化程序(可能是因为不会超出必要的“旧”代码)。
因此,this online c++ standard draft中定义的初始化列表禁止这样的缩小:
8.5.1聚合
(2)当初始化列表初始化聚合时,如 在[dcl.init.list]中指定,初始化列表的元素是 作为聚合成员的初始化者,正在增加 下标或成员顺序。每个成员都是从中复制初始化的 相应的初始化子句。 如果initializer-clause是 表达式和缩小转换([dcl.init.list])是必需的 转换表达式,程序格式不正确。 ...
BTW:如果你使用像const char data { 0x80 }
这样的大括号初始值设定项,你也会遇到错误。因此更严格的规则是由于大括号初始化器/初始化器列表,而不是由于您是初始化数组还是标量值。