为什么"字符串数组的初始化字符串太长" C&编译好不是在C ++中?

时间:2015-02-10 14:15:29

标签: c++ c string gcc g++

以下程序在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编译器。

4 个答案:

答案 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会。