什么语言标准允许忽略固定大小数组上的空终止符?

时间:2016-06-16 14:06:46

标签: c++ c arrays c-strings array-initialization

我们正在将C代码转换为C ++ 我注意到以下代码在C中定义良好,

int main(){

  //length is valid. '\0' is ignored
  char  str[3]="abc";
}

Array initialization所述:

  

"如果已知阵列的大小,则可能比阵列的大小小1   字符串文字,在这种情况下,终止空字符是   。忽略"

但是,如果我要在C ++中构建相同的代码,我会收到以下C ++错误:

error: initializer-string for array of chars is too long
[-fpermissive]    char  str[3]="abc";

我希望有人可以对此进行阐述。

问题:
代码示例在所有C语言标准中是否有效?
它在所有C ++语言标准中都无效吗? 是否有一种原因在一种语言中有效而在另一种语言中无效?

2 个答案:

答案 0 :(得分:16)

您在此处看到的是C和C ++中cstring的初始化规则的不同之处。在C11§6.7.9/ 14中我们有

  

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

强调我的

因此,只要数组对于排除空终止符的字符串足够大,它就是有效的。所以

log("ID: %s Function: %s", res[0].c_str(), res[1].c_str());

是否有效C.在C ++ 14中,管理[dcl.init.string] / 2状态的规则

  

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

继续显示以下代码是错误

char  str[3]="abc";

因此,在C ++中,您必须为整个字符串文字提供足够的存储空间,包括空终止符。

答案 1 :(得分:5)

  

代码示例是否在所有C语言标准中都有效?

请注意,一次只有一个ISO标准生效; C2011取代了C99,取代了C89。

我认为它应该在任何一个标准下有效。

  

所有C ++语言标准都无效吗?

与上述相同,只需更改"有效"到"无效"。

  

是否有一种语言在一种语言中有效而在另一种语言中无效?

最有可能的是,它在C中保持有效,以免破坏任何依赖于该行为的遗留代码。在C之后大约十年左右出现了C ++,并试图解决C的一些缺点,这是插入漏洞的漏洞之一。

许多现代编程语言都是对早期语言的迭代和改进; C是B类型系统,C ++是C,支持OO,类型安全性更好,Java和C#是C ++,具有较少的不确定行为等。