使用整数文字初始化 char 数组和 char 的区别

Difference in initializing char-array and char with integer literals

在我的系统上(4.13.11-1-ARCH,gcc 7.2.0charsigned。当用这样的 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 } 这样的大括号初始值设定项,你也会得到一个错误。因此,更严格的规则是由于大括号初始化器/初始化器列表,而不是由于您是初始化数组还是标量值。