Why "initializer-string for array of chars is too long" compiles fine in C & not in C++?
Following program compiles fine in C with warnings but fails in compilation in C++. Why? What is the reason?
#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;
}
The warning:
Warning:[Error] initializer-string for array of chars is too long [-fpermissive] enabled by default
But if the program is compiled as C++ program then C++ compiler gives following error:
[Error] initializer-string for array of chars is too long [-fpermissive]
I am using GCC 4.8.1 compiler.
Short answer: Because C and C++ are different languages with different rules.
Long answer: In both cases the reason is that the array is too small for the string literal. The literal consists of the five visible characters, with a zero terminator on the end, so the total size is 6.
In C, you're allowed to initialise an array with a string that's too long; extra characters are simply ignored:
C99 6.7.8/14: An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character 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.
The compiler helpfully warns that the string is too large, since it almost certainly indicates an error; but it can't reject the code unless you tell it to treat warnings as errors.
In C++, the initialiser isn't allowed to be larger than the array:
C++11 8.5.2/2: There shall not be more initializers than there are array elements.
so, for that language, the compiler should give an error.
In both languages, when you want a character array to be the right size for a string literal initialiser, you can leave the size out and the compiler will do the right thing.
char a[] = "hello"; // size deduced to be 6
The problem is in below line
char a[5]="Hello";
There is no space left to store the terminating null.
By default, gcc
does not produce any errors for this case with -fpermissive
option enabled. So, it compiles fine in C
.
As per the requirement from the language standards,
- For
C99
standard, chapter 6.7.9, paragraph 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.
- For
C++11
, chapter 8.5.2, paragraph 2
There shall not be more initializers than there are array elements.
So, the code compiles (with warnings) with gcc
, produces error with g++
.
A valid string in C and C++ should have a \0
terminator and in
char a[5]="Hello";
There is no space for null terminator and a is not a valid string.
So this might not be a error in C but you are bound to hit with issues when using in-built string functions like strlen()
and family.