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

What language standards allow ignoring null terminators on fixed size arrays?

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

int main(){

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

正如 Array initialization 中所述:

"If the size of the array is known, it may be one less than the size of the string literal, in which case the terminating null character is ignored."

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

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

我希望有人能解释一下。

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

您在这里看到的是 C 和 C++ 中 cstring 的初始化规则的差异。在 C11 §6.7.9/14 中我们有

An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

强调我的

因此只要数组足够大以容纳不包括空终止符的字符串,它就是有效的。所以

char  str[3]="abc";

是有效的 C。然而在 C++14 中,在 [dcl.init.string]/2 状态

中找到了管理它的规则

There shall not be more initializers than there are array elements.

然后继续显示下面的代码是错误的

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

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

Is the code example valid in all C language standards?

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

不过,我相信它在任何一个标准下都应该有效。

Is it invalid in all C++ language standards?

同上,将"valid"改为"invalid"即可。

Is there a reason that is valid in one language but not another?

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

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