user12184817
user12184817

Reputation:

What is and how to solve the warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] when printing it out

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

Answers (2)

dbush
dbush

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

0___________
0___________

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

Related Questions