%p and different pointer representations
Steve Summit
scs at adam.pika.mit.edu
Sat Feb 25 16:46:25 AEST 1989
In article <1089 at vicorp.UUCP> charlie at vicorp.UUCP (Charlie Goldensher) writes:
>In article <9382 at bloom-beacon.MIT.EDU>, scs at adam.pika.mit.edu (Steve Summit) writes:
>> No, I just use %p.
>That's fine if you don't expect to port the code to another machine.
>But be aware that not all versions of printf provide the %p option.
Yes, but see below.
In article <234 at mstan.Morgan.COM> dff at Morgan.COM (Daniel F. Fisher) writes:
>To what type should a pointer argument be cast when passing it to
>fprintf() for printing using the %p conversion specifier?
An excellent question. The previously-posted answers (cast to void *)
are correct, as far as the standard goes. The case of the 80x86
(IBM PC et al) is, as usual, er, "enlightening." (I never think
of peering down cesspools as being particularly enlightening;
"engloomening" or "endrearening," perhaps.)
Under Microsoft's PC C compiler (I don't know about others), %p
expects a 32-bit ("far") pointer, in all memory models. Therefore,
the pointer passed must, in general, be cast to "void far *".
Although this, I suppose, violates the standard, it's probably
the right solution for that architecture, since not forcing a far
pointer admits the possibility of losing information. (You're
probably printing a pointer because you need to know its value;
therefore having printf throw half of it away would not be
terribly useful.)
Note that I am not defending the 80x86, nor excusing Microsoft
for violating the forthcoming standard (it's hardly the first
time, anyway). I do think Microsoft's compromise was a good one,
under the circumstances. (A better one might have been to make
%p strictly standard-conforming albeit potentially useless, and
use %P as a nonstandard extension to force 32 bit pointers. This
idea has other problems, however.)
Although I've been using %p regularly on the PC, I hadn't thought
about its implications until Daniel asked his question. I'm
afraid that one of two conclusions is inescapable:
1. The ANSI standard is flawed, as far as %p is concerned, or
2. an 80x86 that supports mixed-model programming cannot
support C.
I've been impressed by the number of architectural abominations
that turn out to be compatible with C, given correctly-written,
portable code. The extent to which this is true is a tribute to
Dennis Ritchie's wisdom and foresight. (A case in point is the
recent frequent discussion of the inadvisability of simulating
non-zero-based arrays with "funny" pointers to where [0] would
be. Such pointers have been illegal since at least 1978, yet
most of us have only recently come face-to-face with machines
which actually disallow them.)
That %p may not enjoy this kind of widespread, forward-thinking
portability is not a disparagement of X3J11. (Before anyone gets
offended, this means I'd go with conclusion 2 above, at the risk
of alienating all of the 80x86 aficionadoes in the world, both of
them.) %p has proved to be quite useful; it fills a need and I'm
glad it was added. If nothing else, this difficulty merely lends
further credence to a truth many have long known: segmented
architectures are a crime against the industry. (Intel and IBM
are guilty of mass programmer genocide for foisting it upon the
world as the people's architecture of choice.)
In practice, printing pointers is pretty unportable, but it isn't
much of a problem. (Where's the peck of pickled peppers Peter
Piper picked?) I can think of few uses of %p outside of
debugging code, and it's less important that debugging code be
portable. (I usually get most of the bugs out before I start
porting.) The few exceptions I can think of are programs like
linkers that want to print addresses, but those programs aren't
terribly portable, either.
To summarize, don't lose much sleep over %p difficulties.
Steve Summit
scs at adam.pika.mit.edu
More information about the Comp.lang.c
mailing list