1

I am new to c++ language,recently, as I was taught that:

  • we should put '\0' at the end of char array while doing initialization ,for example :

    char x[6] = "hello"; //OK

  • However,if you do :

    char x[5] = "hello";

    Then this would raise the error :

    initializer-string for array of chars is too long

Everything goes as I expect until the experssion below does not raise the compile error...:

char x[5] = {'h','e','l','l','o'};

This really confuses me , So I would like to ask two questions :

1.Why doesn't expression char x[5] = "hello"; raise error?

2.To my knowledge,the function strlen() would stop only if it finds '\0' to determine the lengh of char array,in this case,what would strlen(x) return?

Thanks!

Pro_gram_mer
  • 749
  • 3
  • 7
  • 20
  • 3
    First you say `char x[5] = "hello";`generates a compiler error, then you say it does not!? – Werner Henze Mar 05 '21 at 06:56
  • 1
    @WernerHenze He says he was taught that you need to leave space and if you don't there will be an error. I have edited the question to make that clear. – Jerry Jeremiah Mar 05 '21 at 06:59
  • 2
    gcc does raise an error: https://godbolt.org/z/jhenqs, and so do clang and msvc. What compiler with which command line settings did you use? – Werner Henze Mar 05 '21 at 07:02
  • 1
    Without `'\0'`, the behavior of `strlen()` is undefined. The solution to all these issues is to use `std::string` instead of `char[]` – Remy Lebeau Mar 05 '21 at 07:16
  • The `strlen` function will continue until it finds the terminator. If it's not inside the array then `strlen` will go out of bounds and you will have *undefined behavior*. Also, if you have a large array but a small but unterminated string in it then `strlen` will go outside the initialized part of the array, and check the uninitialized and *indeterminate* elements and you'll again have undefined behavior. – Some programmer dude Mar 05 '21 at 07:18
  • Already answered [here](https://stackoverflow.com/a/28434100/1468487) – masterop Mar 05 '21 at 07:19
  • 1
    Are you 100% positive this is C++ code that you are compiling? You tagged this "C++" but you said "c/c++" in your question, which makes it hard for us to be sure we understand what language you are asking about! – David Schwartz Mar 05 '21 at 07:22
  • @WernerHenze i edit my answer,sorry for such big mistake. – Pro_gram_mer Mar 05 '21 at 08:58
  • @DavidSchwartz I use c++ and compile with g++ – Pro_gram_mer Mar 05 '21 at 09:01
  • @RemyLebeau I use g++ to compile and does not give any error off using : char x[5] = {'h','e','l','l','o'}; strlen(x); it retuens 10 . – Pro_gram_mer Mar 05 '21 at 09:03
  • @Pro_gram_mer assigning 5 individual chars to a 5-char array is perfectly legal. The compiler makes no assumptions about the array. Assigning a 6-char string literal to a 5-char array is not legal. – Remy Lebeau Mar 05 '21 at 15:24

2 Answers2

3

The string literal "hello" has six characters, because there's an implied nul terminator. So

char x[] = "hello";

defines an array of six char. That's almost always what you want, because the C-style string functions (strlen, strcpy, strcat, etc.) operate on C-style strings, which are, by definition, nul terminated.

But that doesn't mean that every array of char will be nul terminated.

char x[] = { 'h', 'e', 'l', 'l', 'o' };

This defines an array of five char. Applying C-style string functions to this array will result in undefined behavior, because the array does not have a nul terminator.

You can do character-by-character initialization and create a valid C-style string by explicitly including the nul terminator:

char x[] = { 'h', 'e', 'l', 'l', 'o', '\0' };

This defines an array of six char that holds a C-style string (i.e., a nul terminated sequence of characters).

The key here is to separate in your mind the general notion of an array of char from the more specific notion of an array of char that holds a C-style string. The latter is almost always what you want to do, but that doesn't mean that there is never a use for the former. It's just that the former is uncommon.

As an aside, in C you're allowed to elide the nul terminator:

char x[5] = "hello";

this is legal C, and it creates an array of 5 char, with no nul terminator. In C++ that's not legal.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
1

Why doesn't expression char x[5] = "hello"; raise an error?

This is not true. The appearance of an error is expected in this case.

To my knowledge, the function strlen() would stop only if it finds '\0' to determine the length of the char array, in this case, what would strlen(x) return?

If you can run the code somehow, the program will undergo an undefined-behavior. That is, you will not get what you would expect. The strlen() will only stop counting when it finds a null-terminator, i.e. it may go outside the initialized part of the char array and access the uninitialized ones – it's where the UB is invoked.

Rohan Bari
  • 7,482
  • 3
  • 14
  • 34