Reputation:
I have the following code:
#include<stdio.h>
int main(void){
int array[5]={10,20,30,40,50};
int *p;
p=array;
printf("%p\n", array);
printf("%p\n", p);
printf("%p\n", &array[0]);
printf("%p\n", &p[0]);
printf("%p\n", &(*array));
return 0;
}
Compiling this code with GCC and printing the values of the addresses out with %p
gives the following warnings:
01.c: In function ‘main’: 01.c:7:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", array); ~^ ~~~~~ %ls 01.c:8:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", p); ~^ ~ %ls 01.c:9:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", &array[0]); ~^ ~~~~~~~~~ %ls 01.c:10:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", &p[0]); ~^ ~~~~~ %ls 01.c:11:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", &(*array)); ~^ ~~~~~~~~~ %ls ```
How can I solve them and why are they happening? Also, what is %ls
?
Upvotes: 4
Views: 1222
Reputation: 225047
An object pointer of any type may be implicitly converted to a void *
without a cast, and the reverse is also true.
However, the %p
format specifier to printf
explicitly expects a void *
argument, and because printf
is a variadic function that implicit conversion won't happen.
This is one of the rare cases when an explicit cast to void *
is required:
printf("%p\n", (void *)array);
printf("%p\n", (void *)p);
printf("%p\n", (void *)&array[0]);
printf("%p\n", (void *)&p[0]);
printf("%p\n", (void *)&(*array));
On most implementations you're likely to come in contact with, objects pointers and void *
have the same representation. However that is not necessarily true in general, and failing to cast can cause undefined behavior on systems where this is not true.
In contrast, calling the function foo
below does not require a cast:
void foo(void *p)
{
printf("p=%p\n", p);
}
int main()
{
int x;
foo(&x);
}
Because the type of the parameter is known at compile time.
Upvotes: 5
Reputation: 68009
it needs another type of pointer. You need to cast it to void *
printf("%p\n", array);
=> printf("%p\n", (void *)array);
Upvotes: 0