Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > printf() and void *

Reply
Thread Tools

printf() and void *

 
 
Ioannis Vranos
Guest
Posts: n/a
 
      03-02-2008
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?
 
Reply With Quote
 
 
 
 
Harald van Dijk
Guest
Posts: n/a
 
      03-02-2008
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. There are no implicit conversions from other pointer types to
void * in the variable arguments of a function, so if any pointer type
would be accepted, how could printf know which one was passed?
 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      03-02-2008
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 *)&mp;
size_t len = sizeof mp;
while(len--)
{
printf("%02X", *ucp++);
}
puts("");

return 0;
}

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-02-2008
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 *)&mp;
> 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"
 
Reply With Quote
 
Harald van Dijk
Guest
Posts: n/a
 
      03-02-2008
On Sun, 02 Mar 2008 18:33:12 +0000, Richard Heathfield wrote:
> 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 *)&mp; size_t len = sizeof mp;
> while(len--)
> {
> printf("%02X", *ucp++);
> }
> puts("");
>
> return 0;
> }
>
> <snip>


Your example prints the representation of a function pointer, not its
value. If multiple function pointer representations exist for one value,
there is no portable way to print the value in such a way that the
different representations become indistinguishable.
 
Reply With Quote
 
Ioannis Vranos
Guest
Posts: n/a
 
      03-02-2008
Harald van Dijk wrote:
> 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. There are no implicit conversions from other pointer types to
> void * in the variable arguments of a function, so if any pointer type
> would be accepted, how could printf know which one was passed?



In printf() in general, if we want to print the numeric value of a
signed char and of an unsigned char using %d and %u respectively, should
we cast the variable value to the expected type (int and unsigned
respectively)?
 
Reply With Quote
 
santosh
Guest
Posts: n/a
 
      03-02-2008
Ioannis Vranos wrote:

> Harald van Dijk wrote:
>> 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. There are no implicit conversions from other pointer
>> types to void * in the variable arguments of a function, so if any
>> pointer type would be accepted, how could printf know which one was
>> passed?

>
>
> In printf() in general, if we want to print the numeric value of a
> signed char and of an unsigned char using %d and %u respectively,
> should we cast the variable value to the expected type (int and
> unsigned respectively)?


It shouldn't be necessary, at least as far as I can see.

 
Reply With Quote
 
Micah Cowan
Guest
Posts: n/a
 
      03-02-2008
Ioannis Vranos <> writes:

> Harald van Dijk wrote:
>> 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. There are no implicit conversions from other
>> pointer types to void * in the variable arguments of a function, so
>> if any pointer type would be accepted, how could printf know which
>> one was passed?

>
>
> In printf() in general, if we want to print the numeric value of a
> signed char and of an unsigned char using %d and %u respectively,
> should we cast the variable value to the expected type (int and
> unsigned respectively)?


If you're going to use %u for unsigned char, yeah, a cast is a good
idea for maximally correct code. Using %d for either char, signed char
or unsigned char does not require a cast, as it will be promoted to
int in any case.

--
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      03-03-2008
Keith Thompson <ks...@mib.org> wrote:
> Richard Heathfield <r...@see.sig.invalid> writes:
> > #include <stdio.h>
> >
> > int main(void)
> > {
> > * int (*mp)(void) = main;
> > * unsigned char *ucp = (unsigned char *)&mp;
> > * size_t len = sizeof mp;
> > * while(len--)
> > * {
> > * * printf("%02X", *ucp++);
> > * }
> > * puts("");

>
> > * return 0;
> > }

>
> On a system with CHAR_BIT > 8, the above would wor[k],
> but it could produce ambiguous results. *For example,
> the output "12345" could be result of bytes 0x123 and
> 0x45 or 0x12 and 0x345.


Then fix it dear Henry.

#define CHAR_NIBBLES ((CHAR_BIT + 3)/4)
printf("%0*X", CHAR_NIBBLES, 0u + *ucp++);

<snip>
> 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.


Neither is intelligible IMO. But the advantage of
printing bytes is that you _know_ the format (and
width) of the output. That is quite significant in
the hand full of cases where you actually _want_
to print an address!

--
Peter
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      03-03-2008
Harald van D©¦k <true...@gmail.com> wrote:
> ... [the] example prints the representation of a function
> pointer, not its value.


It's value is determined by the representation.

> If multiple function pointer representations exist for
> one value, there is no portable way to print the value
> in such a way that the different representations become
> indistinguishable.


How is this any different to the case for %p? The only
thing you're guaranteed is that if you read via %p you'll
get a pointer that compares equal to the original.

The 'hex dump' approach has the same guarantee.

--
Peter
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What is the difference between void proba(); and void proba(void); ??? PencoOdStip@gmail.com C++ 1 05-23-2007 07:12 PM
what is the difference, void func(void) and void fucn() noblesantosh@yahoo.com C Programming 5 07-22-2005 04:38 PM
"void Method()" vs "void Method(void)" Ollej Reemt C++ 7 04-22-2005 03:47 AM
returning a void (*)(void) Sergio C++ 6 01-05-2005 08:30 PM
`void **' revisited: void *pop(void **root) Stig Brautaset C Programming 15 10-28-2003 09:03 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57