468,457 Members | 1,595 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,457 developers. It's quick & easy.

printf() and void *

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?
Mar 2 '08 #1
15 7392
Harald van Dijk <true...@gmail.comwrote:
... [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
Mar 3 '08 #2
On Sun, 02 Mar 2008 19:45:29 -0800, Peter Nilsson wrote:
Harald van D캐k <true...@gmail.comwrote:
>... [the] example prints the representation of a function pointer, not
its value.

It's value is determined by the representation.
Of course, but that's true for all types. Should we start printing 1.01 as
a series of bytes too, then?
>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.
If you print the same value to printf twice, you can be sure you get the
same string twice. If you print the representation of two identical values
twice, you can't be sure you get the same string twice.
Mar 3 '08 #3
On Mar 3, 12:19 am, Harald van Dijk <true...@gmail.comwrote:
On Sun, 02 Mar 2008 19:45:29 -0800, Peter Nilsson wrote:
Harald van Dijk <true...@gmail.comwrote:
... [the] example prints the representation of a function pointer, not
its value.
It's value is determined by the representation.

Of course, but that's true for all types. Should we start printing 1.01 as
a series of bytes too, then?
Isn't it what "binary file formats" is about?
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.

If you print the same value to printf twice, you can be sure you get the
same string twice. If you print the representation of two identical values
twice, you can't be sure you get the same string twice.
You can not be sure that you'll get two identical
strings from printf("%p\n%p\n", p, p). printf() is
"better" only in that scanf() will be able to read
the string back; the "quality" of output may be
"worse" or "better" in either case.

Anyway, it was about function pointers, for which
printf() doesn't work, so...

Yevgen
Mar 3 '08 #4
On Sun, 02 Mar 2008 23:48:33 -0800, ymuntyan wrote:
On Mar 3, 12:19 am, Harald van D캐k <true...@gmail.comwrote:
>On Sun, 02 Mar 2008 19:45:29 -0800, Peter Nilsson wrote:
Harald van D캐k <true...@gmail.comwrote:
... [the] example prints the representation of a function pointer,
not its value.
It's value is determined by the representation.

Of course, but that's true for all types. Should we start printing 1.01
as a series of bytes too, then?

Isn't it what "binary file formats" is about?
I meant printing the series of bytes as hexadecimal numbers, which is not
what binary file formats are about.
>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.

If you print the same value to printf twice, you can be sure you get
the same string twice. If you print the representation of two identical
values twice, you can't be sure you get the same string twice.

You can not be sure that you'll get two identical strings from
printf("%p\n%p\n", p, p).
The standard states that "the value of the pointer is converted to a
sequence of printing characters, in an implementation-defined manner."
This, by my reading, does not allow anything other than the value of the
pointer to have an effect on the output. In particular, it does not allow
the representation of the pointer (when multiple representations of the
same value exist) to have an effect.
Mar 3 '08 #5
Barry Schwarz <schwa...@doezl.netwrote:
...
scanf must accept many different kinds of pointers.
*%s requires a char*, %d requires an [int], etc.
True.
>*Therefore, it is not possible to have a rule that says
any pointer in the variadic portion of the argument
list would be "promoted" to void*.
Why not?

[Not that I'd want to see such a rule.]

--
Peter
Mar 4 '08 #6
On Mon, 3 Mar 2008 18:13:09 -0800 (PST), Peter Nilsson
<ai***@acay.com.auwrote:
>Barry Schwarz <schwa...@doezl.netwrote:
>...
scanf must accept many different kinds of pointers.
*%s requires a char*, %d requires an [int], etc.
Interesting that your reader didn't quote what I wrote.
>
True.
>>*Therefore, it is not possible to have a rule that says
any pointer in the variadic portion of the argument
list would be "promoted" to void*.

Why not?
Because then scanf would not be receiving the expected type. Changing
scanf so this could be done was mentioned two sentences later.
>
[Not that I'd want to see such a rule.]

Remove del for email
Mar 4 '08 #7
Peter Nilsson wrote:
Barry Schwarz <schwa...@doezl.netwrote:
>...
scanf must accept many different kinds of pointers.
%s requires a char*, %d requires an [int], etc.

True.
>Therefore, it is not possible to have a rule that says
any pointer in the variadic portion of the argument
list would be "promoted" to void*.

Why not?
They SHOULD be promoted to void. The type required is spelled out
by the format string, so they can always be converted back to the
appropriate form. This is one reason why the format string has to
agree with the types received. All scanf needs to know is in the
format, and in the void* pointer.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Mar 4 '08 #8
Richard Heathfield wrote:
Code that doesn't rely on /any/ implementation-defined (or unspecified or
undefined) behaviour - that is, what the Standard calls a "strictly
conforming program" - is maximally portable, but even such "ideal" code
depends on the very characteristics of the platform that support its
ability to produce output (if indeed it does produce output, which need
not apply to library code, of course).
Erm, yes. Thank you for making that so clear.

ROFL

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto/Projects/Monitor/
Mar 4 '08 #9
On Tue, 04 Mar 2008 10:52:36 -0800, ymuntyan wrote:
Suppose it's a PC with 32-bit pointers, without multiple representations
for the same value, where cast to unsigned int and back is well-
defined.
The following function would be a conforming way to print void* in
printf:

void print_pointer(void *p)
{
static unsigned counter;
printf("'''%08x%08x'''", (unsigned)p, counter++);
}

It prints "extra" here, yes. But that "extra" is not forbidden. I have
no idea why one would do that, but it certainly would be conforming. How
is appending a number worse than prepending "0x"
In your example, what's printed depends on more than the pointer value.
The pointer value is what must be formatted. Not the pointer value and
some other data.
or printing "(nil)"?
That's fine. It depends only on the value of the pointer, nothing else.
fputc() is different, it doesn't have this "implementation-defined
manner" freedom.
And the *printf functions have no freedom in choosing what data to use to
print pointers. They happen to have freedom in choosing how to use that
data, but that's a different issue.
It "writes the character", not a sequence of characters
obtained in an implementation-defined manner.
Right. The character is printed. Not the character and some other data.

If putchar('e') prints "hello", it has written the character. It also
happened to have written other data, but the description of putchar
doesn't say it can't.

It's clear to both of us this logic is invalid.

If printf("%p", p) includes a random number in its output, it has
formatted the pointer value. It also happened to have formatted other
data, but the description of fprintf doesn't say it can't.

I don't seem to be able to convince you this logic is equally invalid.
Whether it's allowed to use the bits from the representation, I don't
know. I'd think it is, but it's a different story anyway.
Mar 4 '08 #10
On Mar 4, 1:08 pm, Harald van Dijk <true...@gmail.comwrote:
On Tue, 04 Mar 2008 10:52:36 -0800, ymuntyan wrote:
Suppose it's a PC with 32-bit pointers, without multiple representations
for the same value, where cast to unsigned int and back is well-
defined.
The following function would be a conforming way to print void* in
printf:
void print_pointer(void *p)
{
static unsigned counter;
printf("'''%08x%08x'''", (unsigned)p, counter++);
}
It prints "extra" here, yes. But that "extra" is not forbidden. I have
no idea why one would do that, but it certainly would be conforming. How
is appending a number worse than prepending "0x"

In your example, what's printed depends on more than the pointer value.
The pointer value is what must be formatted. Not the pointer value and
some other data.
or printing "(nil)"?

That's fine. It depends only on the value of the pointer, nothing else.
And also on the will of implementor who can write "(nil)" or
"0" or what else he likes. Anyway, you claim that the format
of %p output must not depend on the program state; I claim it
may depend on the program state. E.g. implementation could
choose the format on startup, like print "(nil)" if program
started on Monday and print "0" if program started on other
day. Or print "(nil)" when printf is *called* on Monday. Or
append a random number.

I guess we can just agree to disagree here :)
fputc() is different, it doesn't have this "implementation-defined
manner" freedom.

And the *printf functions have no freedom in choosing what data to use to
print pointers. They happen to have freedom in choosing how to use that
data, but that's a different issue.
It "writes the character", not a sequence of characters
obtained in an implementation-defined manner.

Right. The character is printed. Not the character and some other data.

If putchar('e') prints "hello", it has written the character. It also
happened to have written other data, but the description of putchar
doesn't say it can't.
Description of files says it can't. What's written can be read
back and you'll know that more than one or a wrong character was
written. If it can't be read, then there is simply nothing to
talk about.
It's clear to both of us this logic is invalid.

If printf("%p", p) includes a random number in its output, it has
formatted the pointer value. It also happened to have formatted other
data, but the description of fprintf doesn't say it can't.
So printf("%p") *is* different in this respect from putchar().

Yevgen
Mar 4 '08 #11
Barry Schwarz wrote:
Peter Nilsson <ai***@acay.com.auwrote:
>Barry Schwarz <schwa...@doezl.netwrote:
>>...
scanf must accept many different kinds of pointers.
%s requires a char*, %d requires an [int], etc.

Interesting that your reader didn't quote what I wrote.
Hm. According to mine, it did.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
--
Posted via a free Usenet account from http://www.teranews.com

Mar 4 '08 #12
CBFalconer said:
Barry Schwarz wrote:
>Peter Nilsson <ai***@acay.com.auwrote:
>>Barry Schwarz <schwa...@doezl.netwrote:
...
scanf must accept many different kinds of pointers.
%s requires a char*, %d requires an [int], etc.

Interesting that your reader didn't quote what I wrote.

Hm. According to mine, it did.
<sighRead it again, Chuck.

--
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
Mar 4 '08 #13
On Tue, 04 Mar 2008 11:38:03 -0800, ymuntyan wrote:
On Mar 4, 1:08 pm, Harald van D캐k <true...@gmail.comwrote:
>On Tue, 04 Mar 2008 10:52:36 -0800, ymuntyan wrote:
It "writes the character", not a sequence of characters obtained in
an implementation-defined manner.

Right. The character is printed. Not the character and some other data.

If putchar('e') prints "hello", it has written the character. It also
happened to have written other data, but the description of putchar
doesn't say it can't.

Description of files says it can't. What's written can be read back and
you'll know that more than one or a wrong character was written. If it
can't be read, then there is simply nothing to talk about.
If stdout hasn't been redirected (either by the program or the
environment), it usually can't be read back, yet I'm quite sure that
implementations aren't allowed to make putchar('e') print "hello" even if
they can determine with absolute certainty that stdout is not by the
program.
Mar 4 '08 #14
On Tue, 04 Mar 2008 20:51:04 +0100, Harald van D캐k wrote:
If stdout hasn't been redirected (either by the program or the
environment), it usually can't be read back, yet I'm quite sure that
implementations aren't allowed to make putchar('e') print "hello" even
if they can determine with absolute certainty that stdout is not by the
readable ^
program.
Sorry about that.
Mar 4 '08 #15
Richard Heathfield wrote:
CBFalconer said:
>Barry Schwarz wrote:
>>Peter Nilsson <ai***@acay.com.auwrote:
Barry Schwarz <schwa...@doezl.netwrote:
...
scanf must accept many different kinds of pointers.
%s requires a char*, %d requires an [int], etc.

Interesting that your reader didn't quote what I wrote.

Hm. According to mine, it did.

<sighRead it again, Chuck.
All I can see is that he truncated it. Tain't extremely
important. Ahhh - int* became [int].

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Mar 5 '08 #16

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Peter Ammon | last post: by
31 posts views Thread by muralipmanohar | last post: by
188 posts views Thread by infobahn | last post: by
29 posts views Thread by whatluo | last post: by
16 posts views Thread by Jordan Abel | last post: by
10 posts views Thread by lovecreatesbeauty | last post: by
11 posts views Thread by Googy | last post: by
43 posts views Thread by Jrdman | last post: by
reply views Thread by NPC403 | last post: by
1 post views Thread by subhajit12345 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.