将const-string分配给常量大小的char数组,在未使用的数组索引中会发生什么?

时间:2015-01-04 21:59:06

标签: c++ c++11

让我说我有:

char name[16] = "123456789abc";

所以name[11] == 'c'name[12] == '\0'

name[13]是否会依赖于胡言乱语/编译器,或者它是否可靠地成为特定值(例如'\ 0'?)

1 个答案:

答案 0 :(得分:8)

从字符串文字初始化字符数组时,未使用的元素初始化为零。

第8.5.2节有规则:

  

窄字符类型(3.9.1),char16_t数组,char32_t数组或wchar_t数组的数组可以通过窄字符串文字char16_t初始化字符串文字,char32_t字符串文字或宽字符串文字,或者用括号括起来的适当类型的字符串文字(2.14.5)。字符串文字值的连续字符初始化数组的元素。

     

没有比数组元素更多的初始化器。

     

如果初始化器的数量少于数组元素,则未明确初始化的每个元素都应进行零初始化(8.5)。

因此,它们将为零。保证。

访问它们并非未定义的行为。


如果您从字符列表char name[16] = { '1', '2', '3', '4', '5', 0 };初始化,那么您将处于聚合初始化领域,这会通过不同的路径提供相同的结果。

当使用聚合初始化并且初始化器的数量少于聚合的元素时,剩余部分的值是初始化的(除非在聚合类型的定义中有 brace-or-equal-initializer )。

该规则见8.5.1节

  

如果初始化子句的数量超过要初始化的成员或元素的数量,则初始化列表格式不正确。

     

如果列表中的初始化子条款少于聚合中的成员,则未明确初始化的每个成员应从其大括号或等号初始值初始化,或者如果没有大括号 - or-equal-initializer,来自空的初始化列表(8.5.4)。

并且有一个例子:

struct  S  {  int  a;  const  char*  b;  int  c;  int  d  =  b[a];  };
S  ss  =  {  1,  "asdf"  };
     

使用ss.a初始化1ss.b "asdf"ss.c初始化int{}形式的表达式值(那   是,0 )和ss.d,其值为ss.b[ss.a](即's'


C ++ 03没有明确声明额外元素将在字符数组规则中进行零初始化。另一方面,聚合规则基本相似,并保证值初始化,始终( brace-or-equal-initializer 在C ++ 11中引入)。

C99第6.7.8节在两种情况下均提供零初始化,即:

  

如果括号括起的列表中的初始值设定项少于元素或成员   用于初始化已知数组的字符串文字中的聚合或更少字符   大小比数组中的元素大,其余的聚合应该是   隐式初始化与具有静态存储持续时间的对象相同。

当然,具有静态存储持续时间的对象已预先初始化为零。