473,401 Members | 2,068 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,401 software developers and data experts.

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 8436
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.
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 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?
>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 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?
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 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?
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 D©¦k <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 Dijk <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 Dijk 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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Peter Ammon | last post by:
It's my understanding that the printf() function is declared as int printf(const char * restrict format, ...); in stdio.h. And loosely speaking, if a parameter is declared as restricted, then...
31
by: muralipmanohar | last post by:
Hello all , I need a help on this code kindly help me out for the below code I worked on the Turboc the result I was expecting was different from what has been printed I have indicated the line...
188
by: infobahn | last post by:
printf("%p\n", (void *)0); /* UB, or not? Please explain your answer. */
29
by: whatluo | last post by:
Hi, c.l.cs I noticed that someone like add (void) before the printf call, like: (void) printf("Timeout\n"); while the others does't. So can someone tell me whether there any gains in adding...
16
by: Jordan Abel | last post by:
I have written this function and was wondering if anyone else could point out if there's anything wrong with it. The purpose is to substitute for printf when in a situation where low-level I/O has...
10
by: lovecreatesbeauty | last post by:
Is parameter type conversion required for the 2nd argument on printf("%p", (void *)&i); ? But one would never call memcpy like: memcpy((void *)pi, (void *)pj, sizeof *pj); /*memcpy((void *)pi,...
11
by: Googy | last post by:
Hi friends!! As we know that the input parameters in a function is fixed when the function is defined but how does printf processes variable number of input arguments ? For example: 1....
2
by: rameshbabupeddapalli | last post by:
Hi, I want to create my own variable length parameters function it should work like printf() function. When i write the program as given below it's working fine #include<stdio.h> ...
43
by: Jrdman | last post by:
someone has an idea on how the printf function is programmed ?
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.