为什么“字符串数组的初始化字符串太长”在C中编译得很好而不是在C ++中编译?

以下程序使用警告在C中编译好,但在C ++中编译失败。 为什么? 是什么原因?

#include  int main(void) { char a[5]="Hello"; a[0]='y'; puts(a); for(int i=0;i<5;i++) printf("%c",a[i]); return 0; } 

警告:

 Warning:[Error] initializer-string for array of chars is too long [-fpermissive] enabled by default 

但是如果程序编译为C ++程序,则C ++编译器会出现以下错误:

 [Error] initializer-string for array of chars is too long [-fpermissive] 

我正在使用GCC 4.8.1编译器。

简短回答:因为C和C ++是不同的语言,具有不同的规则。

答案很长:在这两种情况下,原因是数组对于字符串文字来说太小了。 文字由五个可见字符组成,末尾有一个零终结符,因此总大小为6。

在C中,您可以使用太长的字符串初始化数组; 额外的字符被简单地忽略:

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

编译器有用地警告字符串太大,因为它几乎肯定表示错误; 但它不能拒绝代码,除非你告诉它将警告视为错误。

在C ++中,不允许初始化程序大于数组:

C ++ 11 8.5.2 / 2:初始化器不应多于arrays元素。

因此,对于该语言,编译器应该给出错误。

在这两种语言中,当您希望字符数组的大小适合字符串文字初始化时,您可以保留大小,编译器将做正确的事情。

 char a[] = "hello"; // size deduced to be 6 

问题出在下面

 char a[5]="Hello"; 

没有剩余空间来存储终止空值。

默认情况下,在启用了-fpermissive选项的情况下, gcc不会为此情况产生任何错误。 所以,它在C 编译得很好

根据语言标准的要求,

  • 对于C99标准,第6.7.9章第14段,

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

  • 对于C++11 ,第8.5.2章,第2段

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

因此,代码用gcc编译(带警告),用g++产生错误。

C和C ++中的有效字符串应该有一个\0终止符并且在

 char a[5]="Hello"; 

null终止符没有空格,a不是有效字符串。

因此,这可能不是C中的错误,但在使用内置字符串函数(如strlen()和family strlen() ,您肯定会遇到问题。

因为“Hello”是6个char长,而没有-fpermissive g ++不会用它初始化5个char数组,但是gcc会。