printf pointer argument type warning?

2019-06-21 19:22发布

问题:

Is there a good way to get rid of the following warning? I know it's a type issue in that I'm passing a unsigned long pointer and not an unsigned long, but does printf somehow support pointers as arguments? The pedantic in me would like to get rid of this warning. If not, how do you deal with printing de-referenced pointer values with printf?

#include <stdio.h>

int main (void) {
    unsigned long *test = 1;
    printf("%lu\n", (unsigned long*)test);
    return 0;
}

warning: format specifies type 'unsigned long' but the argument has type

回答1:

unsigned long *test = 1;

is not valid C. If you want to have a pointer to an object of value 1, you can do:

unsigned long a = 1;
unsigned long *test = &a;

or using a C99 compound literal:

unsigned long *test = &(unsigned long){1UL};

Now also:

printf("%lu\n", (unsigned long*)test);

is incorrect. You actually want:

printf("%lu\n", *test);

to print the value of the unsigned long object *test.

To print the test pointer value (in an implementation-defined way), you need:

printf("%p\n", (void *) test);


回答2:

You don't really need to typecast test, the %p will take any pointer (even though the spec says it takes a void*). Using the %p conversion specifier is the safest (and amazingly, most portable) mechanism to print a pointer via printf.

#include <stdio.h>

int main (void) {
    unsigned long ul = 1;
    unsigned long *test = &ul;
    printf("%p\n", test);
    return 0;
}

EDIT: Oh yeah, and also be careful trying to use types like int, long, etc. relying on their type size. This is implementation-dependent and can (and does) change on varying platforms and compilers for those platforms. The C standard just says that long has to be at least as large as int. The POSIX standard for printf "length modifiers" don't specify size in bits, but rather by C type. Thus, you can't presume that sizeof(long) == sizeof(void*) (well, they make that assumption in the Linux kernel, but it's married to gcc where that is always true).



标签: c clang