使用整数文字初始化 char 数组和 char 的区别
Difference in initializing char-array and char with integer literals
在我的系统上(4.13.11-1-ARCH,gcc 7.2.0)char
是 signed
。当用这样的 integer literal
初始化 char
的数组时:
const char mydata[] = {
0x80
};
我收到以下错误:
error: narrowing conversion of ‘128’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
然而,当我改为 const char data = 0x80
时,编译器并不担心任何缩小,尽管它当然会发生。输出为7F
,最高正signed char
值。
问题
为什么编译器不会同样担心两种情况下的截断问题?
这实际上是 {}
初始化应该被优先考虑的原因之一:它不允许缩小转换。与此相反,旧的初始化方式(如 const char data = 0x80
)确实允许缩小转换。
const char c = 0x80
形式的初始值设定项比
初始化列表,后面会介绍。因此可以为初始化器列表定义更严格的规则,而这些规则不适用于 "older" 初始化器(可能是因为不要在不必要的情况下破坏 "older" 代码)。
因此,this online c++ standard draft 中定义的初始化列表禁止这样的缩小:
8.5.1 Aggregates
(2) When an aggregate is initialized by an initializer list, as
specified in [dcl.init.list], the elements of the initializer list are
taken as initializers for the members of the aggregate, in increasing
subscript or member order. Each member is copy-initialized from the
corresponding initializer-clause. If the initializer-clause is an
expression and a narrowing conversion ([dcl.init.list]) is required to
convert the expression, the program is ill-formed. ...
顺便说一句:如果你使用像 const char data { 0x80 }
这样的大括号初始值设定项,你也会得到一个错误。因此,更严格的规则是由于大括号初始化器/初始化器列表,而不是由于您是初始化数组还是标量值。
在我的系统上(4.13.11-1-ARCH,gcc 7.2.0)char
是 signed
。当用这样的 integer literal
初始化 char
的数组时:
const char mydata[] = {
0x80
};
我收到以下错误:
error: narrowing conversion of ‘128’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
然而,当我改为 const char data = 0x80
时,编译器并不担心任何缩小,尽管它当然会发生。输出为7F
,最高正signed char
值。
问题
为什么编译器不会同样担心两种情况下的截断问题?
这实际上是 {}
初始化应该被优先考虑的原因之一:它不允许缩小转换。与此相反,旧的初始化方式(如 const char data = 0x80
)确实允许缩小转换。
const char c = 0x80
形式的初始值设定项比
初始化列表,后面会介绍。因此可以为初始化器列表定义更严格的规则,而这些规则不适用于 "older" 初始化器(可能是因为不要在不必要的情况下破坏 "older" 代码)。
因此,this online c++ standard draft 中定义的初始化列表禁止这样的缩小:
8.5.1 Aggregates
(2) When an aggregate is initialized by an initializer list, as specified in [dcl.init.list], the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause. If the initializer-clause is an expression and a narrowing conversion ([dcl.init.list]) is required to convert the expression, the program is ill-formed. ...
顺便说一句:如果你使用像 const char data { 0x80 }
这样的大括号初始值设定项,你也会得到一个错误。因此,更严格的规则是由于大括号初始化器/初始化器列表,而不是由于您是初始化数组还是标量值。