初始化char-array和char与整数文字的区别

Mar*_*cus 8 c++ arrays initialization char compiler-warnings

在我的系统上(4.13.11-1-ARCH,gcc 7.2.0)charsigned.当初始化的阵列char具有integer literal这样的:

const char mydata[] = {
    0x80
};
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

error: narrowing conversion of ‘128’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
Run Code Online (Sandbox Code Playgroud)

但是,当我改为做const char data = 0x80编译器并不担心任何缩小时,尽管它当然发生了.输出是7F最高的正值signed char.

为什么编译器在两种情况下都不会同样担心截断?

for*_*818 5

这实际上是为什么{}应该首选初始化的原因之一:它不允许缩小转换.与此相反,旧的初始化方式(如同const char data = 0x80)确实可以缩小转换范围.


Ste*_*ner 2

形式的初始值设定项const char c = 0x80是比初始值设定项列表更古老的构造,后者是稍后引入的。因此,可以为初始化器列表定义更严格的规则,而这些规则不适用于“较旧的”初始化器(可能是因为不要过度破坏“较旧的”代码)。

因此,在线 C++ 标准草案中定义的初始值设定项列表禁止此类缩小:

8.5.1 聚合

(2) 当聚合由初始值设定项列表初始化时,如 [dcl.init.list] 中所指定,初始值设定项列表的元素将按递增的下标或成员顺序被视为聚合成员的初始值设定项。每个成员都是从相应的初始化子句复制初始化的。如果初始化子句是一个表达式并且需要缩小转换 ([dcl.init.list]) 来转换该表达式,则该程序格式错误。...

顺便说一句:如果您使用类似的大括号初始化程序const char data { 0x80 },您也会收到错误。因此,更严格的规则是由于大括号初始化器/初始化器列表,而不是由于初始化数组还是标量值。