Possible Duplicate:
Correct format specifier to print pointer (address)?
When printing a pointer using printf
, is it necessary to cast the pointer to void *
? In other words, in code like
#include <stdio.h>
int main() {
int a;
printf("address of a = %p\n", &a);
}
should the argument really be (void *) &a
? gcc
doesn't seem to give any warnings when no explicit cast is made.
Yes, the cast to void*
is required.
int a;
printf("address of a = %p\n", &a);
&a
is of type int*
; printf's "%p"
format requires an argument of type void*
. The int*
argument is not implicitly converted to void*
, because the declaration of printf
doesn't provide type information for parameters other than the first (the format string). All arguments after the format string have the default argument promotions applied to them; these promotions do not convert int*
to void*
.
The likely result is that printf
sees an argument that's really of type int*
and interprets it as if it were of type void*
. This is type-punning, not conversion, and it has undefined behavior. It will likely happen to work if int*
and void*
happen to have the same representation, but the language standard does not guarantee that, even by implication. And the type-punning I described is only one possible behavior; the standard says literally nothing about what can happen.
(If you do the same thing with a non-variadic function with a visible prototype, so the compiler knows at the point of the call that the parameter is of type void*
, then it will generate code to do an implicit int*
-to-void*
conversion. That's not the case here.)
Is this a C or a C++ question? For C++, it seems that according to 5.2.2 [expr.call] paragraph 7 there isn't any implicit conversion to void*
. It seems that C99's 6.5.2.2 paragraph 6 also doesn't imply any explicit promotion of pointer types. This would mean that an explicit cast to void*
is required as pointer types can have different size (at least in C++): if the layout of the different pointer types isn't identical you'd end up with undefined behavior. Can someone point out where it is guaranteed that a pointer is passed with the appropriate size when using variable argument lists?
Of course, being a C++ programmer this isn't much of a problem: just don't use functions with variable number of arguments. That's not a viable approach in C, though.
I think it might be necessary to cast. Are we certain that the size of pointers is always the same? I'm sure I read on stackoverflow recently that the size (or maybe just the alignment?) of a struct*
can be different to that of a union*
. This would suggest that one or both can be different from the size of a void*
.
So even if the value doesn't change much, or at all, in the conversion, maybe the cast is needed to ensure the size of the pointer itself is correct.
In print
, %p
expects a void*
so you should explicitly cast it. If you don't do so, and if you are lucky then the pointer size and pointer representation might save the day. But you should explicitly cast it to be certain - anything else is technically undefined behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With