Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we have to cast an array to type[] when initialising a pointer?

Tags:

arrays

c

pointers

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?

like image 976
Kaiyaha Avatar asked Apr 09 '26 04:04

Kaiyaha


2 Answers

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.

like image 64
dbush Avatar answered Apr 10 '26 18:04

dbush


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.

like image 33
Barmar Avatar answered Apr 10 '26 17:04

Barmar