Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

warning: format ‘%p’ expects argument of type ‘void *’, but argument 3 has type ‘char **’

Tags:

c

pointers

I'm trying to print out the value of argv at this point in my code, but when I try to compile it, I get warning: format ‘%p’ expects argument of type ‘void *’, but argument 3 has type ‘char **. I'm not sure what this warning means though. Is %p not meant to be used for argv even though it's a pointer?

int main(int argc, char* argv[])
{
    printf("%s%p", "argv = ", argv);
}
like image 878
user7549456 Avatar asked Sep 07 '18 06:09

user7549456


2 Answers

So why don't you cast it?

printf("argv = %p\n", (void *)argv);`

The %p pointer is specified (POSIX printf(); C11 §7.21.6.1 The fprintf function):

p — The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.

Since char ** is not a void *, you need to do the explicit conversion. The compiler isn't allowed by the standard to do the conversion to void * for you — the ellipsis notation in the declaration of printf() means that default argument promotions occur, but that affects only the float type and integer types smaller than int (short, char, etc).

On most machines these days, that's a no-op. On the (long obsolete) machine where I learned to program in C, there weren't void * yet (too old for the standard), but the equivalent was char *, and the value of a char * address for a given memory location was different from the pointer value for any other type — the casts were not optional.

Note that I'm assuming you intend to print the value of the address. If you intend to print the contents, then there's more work to be done.

like image 138
Jonathan Leffler Avatar answered Oct 12 '22 21:10

Jonathan Leffler


Well, not any pointer (type).

According to C11, chapter §7.21.6.1, for the %p conversion specifier,

p

The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.

So, the argument must be of type void * (or, a char*, given they have the same alignment requirements). Any other type of pointers, must be converted through an explicit cast, as there is no default argument promotion for pointers.

Something like

printf("%s%p", "argv = ", (void *)argv);

should do.

like image 21
Sourav Ghosh Avatar answered Oct 12 '22 22:10

Sourav Ghosh