Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why "initializer-string for array of chars is too long" compiles fine in C & not in C++?

Tags:

c++

c

string

gcc

g++

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.

like image 440
Destructor Avatar asked Feb 10 '15 14:02

Destructor


4 Answers

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
like image 101
Mike Seymour Avatar answered Nov 03 '22 10:11

Mike Seymour


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,

  • ForC99 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++.

like image 43
Sourav Ghosh Avatar answered Nov 03 '22 09:11

Sourav Ghosh


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.

like image 27
Gopi Avatar answered Nov 03 '22 09:11

Gopi


Because "Hello" is 6 chars long and g++ without -fpermissive won't initialise a 5 char array with it, but gcc will.

like image 3
Paul Evans Avatar answered Nov 03 '22 08:11

Paul Evans