Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No compiler error when fixed size char array is initialized without enough room for null terminator

Suppose I have the following c char arrays:

char okaysize4[5] = "four";   // line 5
char toosmall4[4] = "four";   // line 6
char toosmall3[3] = "four";   // line 7

When I compile with gcc 4.4.7, I get the following error:

array.c:7: warning: initializer-string for array of chars is too long

This error is expected for line 7, as I am trying to stuff 5 chars ("four" + \0) into a 3 element array. Also no error is expected for line 5 as the 5 element array is big enough.

However I'm surprised there is no similar error for line 6. What ends up getting initialized in toosmall4 is an unterminated string, which can cause all sorts of trouble.

My understanding is that the c string literal "four" should be five characters long, due to the null terminator. In fact sizeof("four") is 5. So why does the compiler not give an error here?

Is there some way I can alter my declaration/definition/initialization so that an error is flagged in this case?

like image 335
Digital Trauma Avatar asked Dec 20 '13 01:12

Digital Trauma


People also ask

Is it possible to initialize a char array with a string?

You can call it a string (if it has a 0 terminator, aka ASCII nul (not NULL, @Baard)), or you can call it a char array. It is allowed to initialize a char array with a string if the array is at least large enough to hold all of the characters in the string besides the null terminator.

Does a string have a null terminator at run time?

At run time, the array b is initialized with the first 2 characters from the string literal, but does not contain the null terminator. ( b is not a string). A string in C is a NULL terminated char-array, so if it's not NULL-terminated it's not a string... just a char-array.

Is it possible to specify the remainder of a char array?

It’s possible to specify only the portion of the elements in the curly braces as the remainder of chars is implicitly initialized with a null byte value. It can be useful if the char array needs to be printed as a character string.

How to initialize 2D char array in C with curly braces?

Use { { }} Double Curly Braces to Initialize 2D char Array in C The curly braced list can also be utilized to initialize two-dimensional char arrays. In this case, we declare a 5x5 char array and include five braced strings inside the outer curly braces. Note that each string literal in this example initializes the five-element rows of the matrix.


1 Answers

This is expected behavior for line 6, from the draft C99 standard section 6.7.8 Initialization paragraph 14 says (emphasis mine):

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.

In the C11 draft standard the relevant section with similar wording is 6.7.9 paragraph 14, and as the C FAQ says:

The array is therefore not a true C string and cannot be used with strcpy, printf's %s format, etc.

As Keith Thompson noted, C++ is stricter, the relevant section in the draft C++ standard says the following:

There shall not be more initializers than there are array elements. [ Example:

char cv[4] = "asdf"; // error

is ill-formed since there is no space for the implied trailing ’\0’. —end example ]

like image 109
Shafik Yaghmour Avatar answered Sep 29 '22 06:09

Shafik Yaghmour