Home > other >  warning: initialization of 'int *' from ' int' makes pointer from integer withou
warning: initialization of 'int *' from ' int' makes pointer from integer withou

Time:03-13

I was studying pointers and this is what i learned:-

int a = 23;
int *ptr = &a;

char b = 'b';
char *pnt = &b;

char *str = "string";

Value assigned to a pointer is an address. So i can't do int *ptr = 7; or char *k = 'c';. But i can do char *str = "string"; because "string" is not a char but an array of some char values, as chars and pointers are quite similar to each other, So in above code if i print printf("%p", str); should print address saved in str which should be the address of starting address of string (This is the 1st part where i want to know i am right or wrong)

So in another way by doing char *str = "string"; i am just creating an array of chars like {'s','t','r','i','n','g'}. (maybe this is going to sound very stupid but that's what it is) So i thought why not try char *str = {'s','t','r','i','n','g'};, i thought that printf("%p\n", str) will again give starting address of string but after getting some weired value and running printf("%c", str) returned 's' i found it is giving the very 1st element of array instead of address. and i tried same with int array and noticed a warning saying

int *array = {1,2,3};

warning: initialization of 'int *' from ' int' makes pointer from integer without a cast

As per my understanding of this, compiler treating {1,2,3} as an int not as an array, i am not sure why but if i cast explicitly it is running fine like int *array = (int[]){1,2,3}. I am not sure why i need to tell explicitly but i think this is how compiler sees it

  • after doing int *array = {1,2,3}; compiler is getting an address of {1,2,3}.
  • but when compiler sees there is an int at that address it is reading that int only
  • and compiler sees it like int *array = 1 not int *array = {1,2,3}

i don't know if my theory is right or not. If not please i want to know why this is happening and why doing char *str = "string" doesn't need any cast.

CodePudding user response:

In C string literals have character array types. For example the string literal "string" is stored in memory as the following array of the type char[7]:

{ 's', 't', 'r', 'i', 'n', 'g', '\0' }

You can check this by using the following call

printf( "sizeof( \"string\" ) = %zu\n", sizeof( "string" ) );

Arrays used in expressions with rare exceptions are implicitly converted to pointers to their first elements.

From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined

So in this declaration

char *str = "string";

the array that corresponds to the stored string literal by the compiler (usually in a string literal pool) is converted to pointer to its first element and the value of the pointer is assigned to the scalar object str.

str is not an array. str is a pointer.

The above declaration may be rewritten also the following way

char *str = &"string"[0];

This declaration

char *str = {'s','t','r','i','n','g'};

is incorrect. A scalar object may be initialized by a braced list that contains only one assignment expression.

From the C Standard (6.7.9 Initialization)

11 The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion); the same type constraints and conversions as for simple assignment apply, taking the type of the scalar to be the unqualified version of its declared type.

You could write for example

char *str = { ( 's','t','r','i','n','g' )};

In this case within the braces there is a primary expression with the comma operator. In fact this declaration is equivalent to

char *str = { 'g' };

and the compiler will issue a message that you are trying to initialize a pointer with an integer.

In this declaration

int *array = (int[]){1,2,3};

there is no casting. The construction (int[]){1,2,3} denotes a compound literal of the type int[3] and again the address of the first element of this array is assigned to the pointer array.

You may imagine the above declaration the following way

int compound_literal[] = { 1, 2, 3 };
int *array = compound_literal;
  • Related