0

In C the string is always terminated with a \0 character, so the length of the string is the number of characters + 1. So, in case you need to initialise a string of 12 characters, you must "allow one element for the termination character" (from p.221, "Beginning C", Horton).

All right, let's try

#include <stdio.h>

int main(void)
{
    char arr1[12] = "Hello world!";
    char arr2[] = "Hello world!";
    printf("\n>%s< has %lu elements", arr1, sizeof(arr1) / sizeof(arr1[0]));
    printf("\n>%s< has %lu elements", arr2, sizeof(arr2) / sizeof(arr2[0]));
    return 0;
}

outputs

>Hello world!< has 12 elements
>Hello world!< has 13 elements

Why the C complier allowed me to create a fixed size array arr1 without a \0 character and added \0 when I asked for a variable sized array arr2?

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
minerals
  • 6,090
  • 17
  • 62
  • 107
  • 2
    It's required by the C Standard to do this. And `arr2` is not variably-sized, its size is fixed, although implicitly. – Ruslan Dec 05 '21 at 16:36
  • 1
    The "c" tag is for the language. "clang" is one of the compilers. – HolyBlackCat Dec 05 '21 at 16:38
  • 4
    The simplest reason why the first array is 12 characters long is because you specifically asked for it to be 12 characters long. Compilers generally do exactly what you tell them even if it isn't necessarily sensible, since they generally think you know better than them. – Tim Seguine Dec 05 '21 at 16:38
  • Then why in the book it is explicitly written that you **must** take "Caution" when you define char arrays. Their size must be at least +1 greater than the number of chars. I am confused. – minerals Dec 05 '21 at 16:42
  • 1
    Because, if you **don't** take caution, and define a 12-char array as you did in your `arr1`, you'll end up with all sorts of errors and undefined behaviour - like if you try to `printf` that string. – Adrian Mole Dec 05 '21 at 16:44
  • Adrian is right. Your first output just came right by luck. It may show some garbage characters after *`Hello world!`* (or maybe a core dump) as it is not null terminated. Just check it here - https://wandbox.org/permlink/xod20yCleCH59nW2 – brc-dd Dec 05 '21 at 16:47
  • @AdrianMole yes, and "all sorts of errors" is the part I needed to understand why. – minerals Dec 05 '21 at 16:48
  • 1
    @minerals the first array isn't guaranteed to be null terminated. The compiler just happened to generate code that resulted in a null terminated string. The printf command read 13 characters(the last of which was luckily a 0). It could have continued reading for an arbitrarily long length resulting in garbage characters or a segmentation fault. – Tim Seguine Dec 05 '21 at 16:50

1 Answers1

4

When you define an array with a fixed size and initialize it with a string literal:

  • If the size is smaller than the number of characters in the string (not counting the terminating null character), the compiler will complain about the mismatch.
  • If the size equals the number of characters in the string (not counting the terminating null character), the compiler will initialize the array with the characters in the string and no terminating null character. This is used to initialize an array that will be used only as an array of characters, not as a string. (A string is a sequence of characters terminated by a null character.)
  • If the size is greater than the number of characters in the string, the compiler will initialize the array with the characters in the string and a terminating null character. Any elements in the array beyond that will also be initialized to zero.

When you define an array without a stated size and initialize it with a string literal:

  • The compiler counts the characters in the string literal, including the terminating null character, and makes that the array size.

These are the rules of the C standard.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 1
    This all seems to be well-covered and explained in the linked duplicate. – Adrian Mole Dec 05 '21 at 16:46
  • @AdrianMole: There was no linked duplicate when I posted. (Actually, Stack Overflow shows the linked duplicate posted nine seconds before my answer, which is odd since questions are usually closed for answers once marked as a duplicate. I suppose the interface is not fully synchronous. In any case, no linked duplicate was visible to me when the answer was posted, and the bulk of it was obviously composed before that.) – Eric Postpischil Dec 05 '21 at 16:50
  • 1
    I wasn't trying to be censorious or judgemental - just pointing out a fact. – Adrian Mole Dec 05 '21 at 16:51
  • @EricPostpischil `not fully synchronous` - [by design](https://meta.stackoverflow.com/a/411496/11683). – GSerg Dec 05 '21 at 19:02