初始化固定大小的char数组时没有编译器错误,没有足够的空间用于null终止符

假设我有以下c char数组:

char okaysize4[5] = "four"; // line 5 char toosmall4[4] = "four"; // line 6 char toosmall3[3] = "four"; // line 7 

当我用gcc 4.4.7编译时,我收到以下错误:

array.c:7:警告:chars数组的初始化字符串太长

第7行预计会出现此错误,因为我试图将5个字符("four" + \0)填充到3个元素数组中。 第5行也不会出现错误,因为5元素数组足够大。

但是我很惊讶第6行没有类似的错误。最终在toosmall4初始化的是一个未toosmall4的字符串,这可能会导致各种麻烦。

我的理解是,由于null终止符,c字符串文字"four"应该是五个字符长。 实际上sizeof("four")是5.那么为什么编译器不会在这里给出错误?

有什么方法可以改变我的声明/定义/初始化,以便在这种情况下标记错误?

这是第6行的预期行为,来自草案C99标准部分6.7.8 初始化14段说( 强调我的 ):

字符类型数组可以由字符串文字初始化,可选地用大括号括起来。 字符串文字的连续字符( 如果有空间或数组大小未知,则包括终止空字符 )初始化数组的元素。

在C11标准草案中,具有相似措辞的相关部分是6.7.914段,而C常见问题解答说 :

因此,该数组不是真正的C字符串,不能与strcpy,printf的%s格式等一起使用。

正如Keith Thompson所说, C ++更严格,C ++标准草案中的相关部分说明如下:

没有比数组元素更多的初始化器。 [例如:

 char cv[4] = "asdf"; // error 

由于隐含的尾随’\ 0’没有空格,因此格式错误。 – 示例]

这是合法的, toosmall4不是一个字符串,而是一个有效的char数组(没有终止空字符)。

参考: C FAQ 。