We do not cast a string when initialise a pointer:
char *string = "Hello World!";
However, if I try to define an array explicitly (whatever it is of), the compiler gives me a warning of type incompatibility:
char *string = {'H', 'e', 'l', 'l', 'o', '\0'};
Casting to char[] works, but I wonder why do we have to cast? Doesn't a compiler see that the initialising value {'H', 'e', 'l', 'l', 'o', '\0'} is already an array? If we initialise an array like string[] the same way, we do not have to cast though. I assume here the compiler sees what the initialising value is, why doesn't it see it when initialising a pointer?
string is a pointer, not an array, so it needs an initializer that is a pointer.
The first code snippet is OK because a string literal has array type, and that array decays into a pointer to its first element.
The second is not OK because you're assigning a set of characters to a pointers. Because string is not an array or struct, only the first member of the initializer list is used. So you have a character constant, which has type int, that you're trying to assign to a pointer.
You say it works if you cast. If you mean this:
char *string = (char []){'H', 'e', 'l', 'l', 'o', '\0'};
Then what you have is actually a compound literal on the right side which has array type, and like the first example an array decays to a pointer to its first member.
When you're initializing a pointer, you have to provide a value that's the address of an object, or a null pointer.
{'H', 'e', 'l', 'l', 'o', '\0'} is not the address of anything. It's the syntax for an initializer list, which can only be used to initialize a variable whose type is an array or structure type.
You haven't actually shown the cast you're talking about, but I assume it's
char *string = (char[]){'H', 'e', 'l', 'l', 'o', '\0'};
It's not actually a cast, although it uses similar syntax.
An initializer list preceded by an array or structure type in parentheses is called a compound literal. It creates an anonymous object of the specified type, and the value is that object.
When used with an array, the value decays to a pointer to the first element of the array, just like any other use of an array in r-value context. This allows you to use it as the initializer of a pointer variable.
So it's effectively equivalent to:
char temp[] = {'H', 'e', 'l', 'l', 'o', '\0'};
char *string = temp;
except that there's no name temp associated with the array.
You don't need this type of syntax when initializing with a string literal, because string literals already construct the array in static memory and evaluate to a pointer to the first element.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With