Richard Heathfield <> writes:
> Harald van D?k said:
>> On Sun, 02 Mar 2008 19:59:19 +0200, Ioannis Vranos wrote:
>>> I recall from previous discussions here, that we must cast a non-void
>>> pointer to void * before printing its value with printf("%p"). Is it
>>> true, and if yes why?
>>
>> Except for function pointers, which can't be printed portably at all, it
>> is true.
>
> Well, no pointer value can be printed portably, since the output associated
> with %p is implementation-defined. But if you mean there's no *technique*
> for printing a function pointer value in ISO C, I must disagree. (If you
> simply mean that there's no printf format specifier for it, then of course
> you're right.)
>
> #include <stdio.h>
>
> int main(void)
> {
> int (*mp)(void) = main;
> unsigned char *ucp = (unsigned char *)∓
> size_t len = sizeof mp;
> while(len--)
> {
> printf("%02X", *ucp++);
> }
> puts("");
>
> return 0;
> }
On a system with CHAR_BIT > 8, the above would wor, but it could
produce ambiguous results. For example, the output "12345" could be
result of bytes 0x123 and 0x45 or 0x12 and 0x345.
I don't believe there are any hosted implementations (i.e., ones
required to support <stdio.h> with CHAR_BIT >

, so this is unlikely
to be an issue in practice -- though the systems, mostly DSPs, that do
have CHAR_BIT > 8 may well support stdio even though they're not
required to.
Another possible issue with the above is the order in which it prints
the bytes. On one system, I ran the above code with an added line:
printf("main = %p\n", (void*)main); /* non-portable extension */
and got:
A4830408
main = 0x80483a4
There are always tradeoffs. If you want to ensure that the output is
sensible for the platform's address representation, *and* if the
implementation supports converting a function pointer to void*, *and*
if you don't mind your code being non-portable, you can use "%p" with
a cast. On systems that don't support the conversion, the code is
likely to be rejected rather than to misbehave silently.
If you want to get *really* fancy, you can write a function that tests
the byte ordering of some integer type, assume that that corresponds
to the pointer representation, and use that to determine the order in
which to display the bytes. And you can insert, say, a ':' character
between successive bytes to ensure it's unambiguous (or you can check
the value of CHAR_BIT).
--
Keith Thompson (The_Other_Keith) <kst->
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"