以下程序在C中编译好并带有警告但在C ++中编译失败。为什么?是什么原因?
#include <stdio.h>
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编译器。
答案 0 :(得分:22)
简短回答:因为C和C ++是不同规则的不同语言。
答案很长:在这两种情况下,原因是数组对于字符串文字来说太小了。文字由五个可见字符组成,末尾有一个零终止符,因此总大小为6.
在C中,您可以使用字符串太长来初始化数组;额外的字符被忽略了:
C99 6.7.8 / 14:字符类型数组可以用字符串文字初始化,可选择用大括号括起来。字符串文字的连续字符(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素。
编译器有用地警告字符串太大,因为它几乎肯定表示错误;但它不能拒绝代码,除非你告诉它将警告视为错误。
在C ++中,初始化者不允许大于数组:
C ++ 11 8.5.2 / 2:初始化器的数量不会超过数组元素。
因此,对于该语言,编译器应该给出错误。
在这两种语言中,当您希望字符数组的大小适合字符串文字初始化时,您可以保留大小,编译器将做正确的事情。
char a[] = "hello"; // size deduced to be 6
答案 1 :(得分:11)
问题出在以下行
char a[5]="Hello";
没有剩余空间来存储终止空值。
默认情况下,gcc
在启用-fpermissive
选项的情况下不会产生任何错误。所以,在C
中编译。
根据语言标准的要求,
C99
标准,第6.7.9章,第14段,字符类型数组可以由字符串文字或UTF-8字符串文字初始化,可选择用大括号括起来。字符串文字的连续字节(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素。
C++11
,第8.5.2章,第2段没有比数组元素更多的初始化器。
因此,代码使用gcc
编译(带警告),产生g++
错误。
答案 2 :(得分:5)
C和C ++中的有效字符串应该有一个\0
终止符并且在
char a[5]="Hello";
null终止符没有空格,a不是有效字符串。
因此,这可能不是C中的错误,但在使用strlen()
和家庭等内置字符串函数时,您一定会遇到问题。
答案 3 :(得分:3)
因为&#34;你好&#34;长度为6 char
,而没有-fpermissive
的g ++不会用它初始化5 char
数组,但gcc会。