初始化char数组和具有整数文字的char时的差异

Difference in initializing char-array and char with integer literals

本文关键字:char 文字 数组 初始化 整数      更新时间:2023-10-16

在我的系统(4.13.11-1-ARCH,gcc 7.2.0)上,charsigned。当用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形式的初始值设定项是一个比初始值设定项列表,稍后将介绍。因此,可以为初始值设定项列表定义更严格的规则,而这些规则不适用于"较旧"的初始值设定值(可能是因为不必破坏"较旧的"代码)。

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

8.5.1骨料

(2) 当聚合由初始值设定项列表初始化时,如在[dcl.init.list]中指定,初始值设定项列表的元素为作为聚合成员的初始值设定项,在递增中下标或成员顺序。每个成员都是从相应的初始值设定项子句如果初始值设定项子句是表达式,并且需要缩小转换([dcl.init.list])转换表达式,程序格式不正确。。。

BTW:如果使用像const char data { 0x80 }这样的大括号初始值设定项,也会出现错误。因此,更严格的规则是由于大括号初始化器/初始化器列表,而不是由于初始化数组还是标量值。