Home > Software engineering >  What is difference of char l[] {'try'} and char l[] {'t', 'r', 'y
What is difference of char l[] {'try'} and char l[] {'t', 'r', 'y

Time:05-05

When I was trying to cout them

char l[] {'t', 'r', 'y'};
std::cout << l << std::endl;

I got try printed in the terminal. However, when I tried this.

char l[] {'try'};

I only got y.

I came to c from python so lots of things don't make sense to me, so can you explain the difference of these two expressions?

CodePudding user response:

None of your examples are valid.

  • The first one has undefined behavior.
    char l[] {'t', 'r', 'y'};
    std::cout << l << std::endl;
    
    Here you define l to be a char[3]. That's fine. Printing it like you do is however not since the operator<< overload you use requires a null terminated string. Your char[3] is not null terminated so the operator<< overload will try to find the null terminator out of bounds which causes undefined behavior. A working variant would have been
    char l[] {'t', 'r', 'y', '\0'};
    
    which would have made it a char[4] with a \0 (null terminator) at the end.
  • The second example tries to create the array from a multibyte character. Single quotes are for individual characters so that's why that interpretation doesn't work. Many compilers will simply refuse to compile it. To create the array from a string literal, use double quotes:
    char l[] {"try"};
    
    or the idiomatic way:
    char l[] = "try";
    
    Both versions will create a null terminated array, just like char l[] {'t', 'r', 'y', '\0'};

CodePudding user response:

char l[] {'t', 'r', 'y'}; defines l to be array of three characters with no terminating null character, so using it in std::cout << l is bad because the insert operator << needs the terminating null character to tell it where the end is.

char l[] {'try'}; defines l to be an array of one character because 'try' is a single number formed from three characters in an implementation-defined way. Since it is only one number, the size of the array l is set to be one element. To initialize l with that number, it is converted to char, which loses information about the three characters.

char l[] {"try"}; would define l to be an array of four characters, because string literals (marked by " instead of ') automatically include a terminating null character. Also, even though a string literal is “one thing,” there is a special rule that says when a string literal is used to initialize an array, its contents are used to initialize the array. So the array size is four elements because there are four characters in the string.

CodePudding user response:

In this declaration

char l[] {'t', 'r', 'y'};

there is declared a character array that contains exactly three characters. As the array does not contain a string (a sequence of characters terminated with the zero or the so-called null character '\0') then the next statement

std::cout << l << std::endl;

invokes undefined behavior because in this case the operator << expects a pointer to a string (an array designator with rare exceptions is converted to pointer to its first element).

Instead you could write for example

std::cout.write( l, sizeof( l ) ) << std::endl;

Otherwise you could initialize the array by a string literal like

char l[] {"try"};

and write

std::cout << l << std::endl;

In this declaration

char l[] {'try'};

there is declared a character array that is initialized by the multicharacter literal 'try' that has an implementation defined value and the type int. Multicharacter literals are conditionally supported.

The compiler should issue a message for such a declaration that there is used a narrowing conversion from int to char.

Again you may not write

std::cout << l << std::endl;

because the array does not contain a string. It contains only one element with an implementation defined value.

Try this code snippet

char l[]{ 'try' };

std::cout << sizeof( l ) << '\n';

To output the array you could write as already shown above

std::cout.write( l, sizeof( l ) ) << std::endl;

CodePudding user response:

When you insert an array into an output stream, the array argument implicitly converts to a pointer to char. When you pass a pointer to char into an output stream, it must point to a null terminated string of characters. If the pointer is not to a null terminated character string, then the behaviour of the program is undefined. Undefined behaviour should be avoided.

char l[] {'t', 'r', 'y'};
std::cout << l << std::endl;

l is an array of 3 characters that does not contain a null terminator character. In this example you insert a pointer to non-null terminated string into an output stream and the behaviour of the program is undefined. The program is broken. Don't do this.

char l[] {'try'};

l is an array of 1 character that does not contain a null terminator character. If you insert this array to an output stream, then the behaviour of the program is undefined. The program is broken. Don't do this.

Note: 'try' is a multicharacter literal. It's type is int and its value is implementation defined. Multicharacter literals aren't useful very often. What you probably intended to do, is to use a string literal:

char l[] = "try";

The string literal "try" is an array of 4 characters; ending in the null terminator character.

  • Related