2

When I try to compile the following:

int main() {
    char a[4] = "1234";  // This string is length 5, no warning
    char b[4] = "12345"; // This string is length 6, produces a warning
}

I get a warning about "initializer-string for char array is too long" or some such only for the second line. does anyone know if this is intentional? Why would the first not produce a warning? I tried both with gcc and clang.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Baruch
  • 20,590
  • 28
  • 126
  • 201
  • Does this answer your question? [Why does gcc allow char array initialization with string literal larger than array?](https://stackoverflow.com/questions/13490805/why-does-gcc-allow-char-array-initialization-with-string-literal-larger-than-arr) – Emoun May 16 '23 at 07:41
  • How did you compile this? You might need to pass some flags to produce warnings. – Martin Baulig May 16 '23 at 07:42
  • On OpenBSD, `clang -c test.c` yields `test.c:3:17: warning: initializer-string for char array is too long [-Wexcess-initializers]`. It might be different with `gcc` on GNU / Linux - although `-Wall` should really enable it. – Martin Baulig May 16 '23 at 07:44
  • @Emoun No. I know about that. But my question is about why there is a warning only if it is too long by at least 2, not by 1. It should either warn in both cases, or not warn in both, no? – Baruch May 16 '23 at 07:46
  • @MartinBaulig That is my question: why does it warn for line 3 and not for line 2? – Baruch May 16 '23 at 07:47
  • 1
    @Baruch Because in C, `char[n]` is an array of `n` characters, just like `int[n]` is an array of `n` integers. In fact, there isn't even anything in the language that dictates that a `char *` is NUL terminated. For the compiler, a `char *` is just a pointer - it doesn't care about size. Only on line 3, the 5 characters "12345" cannot possibly fit into an array of size 4 - hence the compiler warning. – Martin Baulig May 16 '23 at 07:53
  • @MartinBaulig The string literal `"1234"` is however always nul terminated and this is guaranteed. The reason why there's no warning is because of a weird quirk in the C language, left behind since the old "fixed string" days of ancient Unix. And this is a FAQ question by now. – Lundin May 16 '23 at 14:36

1 Answers1

6

In C opposite to C++ you may initialize a character array with a fixed size with a string literal when the terminating zero character '\0' of the string literal is not stored in the initialized array. In this case the array will not contain a string.

From the C Standard (6.7.9 Initialization_

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.

So in this declaration

char a[4] = "1234";

there is no room in the character array for the terminating zero character '\0' of the string literal.

As for this declaration

char b[4] = "12345";

then it breaks the requirement that

2 No initializer shall attempt to provide a value for an object not contained within the entity being initialized.

because there is used the initializer '5' (that is not the terminating zero character) for a character not contained in the array b.

A C++ compiler will issue an error for the both declarations.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335