[comp.lang.c] %p and MSC

kdq@demott.COM (Kevin D. Quitt) (08/03/90)

    %p represents a bug in Microsoft's documentation.  As I had quoted
it earlier, their documentation does indicate that they are not ANSI
compliant; testing, however, has indicated that MSC *is* ANSI compliant
for those models where data and code have the same size pointer (S,L,H). 
Those models with mixed addressing modes (C,M) cause a problem because
it is impossible for printf to differentiate between code and data
pointers.

    Making the best of a bad situation, you can either coerce your
pointers, or use %lp for long pointers and %Np for short.  After all, if
you're really going for compatibility, are you going to use a mixed
model? Also, it seems to me that a program that tries to do anything
significant with %p is probably not really very portable anyway. 


    (With both hands held up over my head, and making V's with my
fingers:  "I am not a Microsoft apologist" )  8-{)}

-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

                96.37% of all statistics are made up.

colin@array.UUCP (Colin Plumb) (08/05/90)

In article <444@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>
>    %p represents a bug in Microsoft's documentation.  As I had quoted
>it earlier, their documentation does indicate that they are not ANSI
>compliant; testing, however, has indicated that MSC *is* ANSI compliant
>for those models where data and code have the same size pointer (S,L,H). 
>Those models with mixed addressing modes (C,M) cause a problem because
>it is impossible for printf to differentiate between code and data
>pointers.

It shouldn't have to... are you passing it something other than void *
(as required in 4.9.6.1)?

Of course, in models where data pointers are smaller than code pointers,
you will encounter the fact that ANSI doesn't guarantee that pointers to
functions can be cast to void * without losing information...  In other
words, there is no ANSI-conformant way to print pointers to functions
(why would you want to in portable code, anyway?)
-- 
	-Colin

scs@adam.mit.edu (Steve Summit) (08/05/90)

In article <1990Aug2.232603.11944@athena.mit.edu> I wrote:
>the Microsoft compilers are not ANSI-compliant in this regard.
>It's not an academic question, either; the correct and portable
>code
>	int *ip;
>	printf("%p\n", (void *)ip);
>will not function as intended under MSC if a small-data memory
>model is used...

I was at least partially wrong, as of MSC version 6.00.  Read on:

In article <444@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>    %p represents a bug in Microsoft's documentation.
>testing... has indicated that MSC *is* ANSI compliant
>for those models where data and code have the same size pointer (S,L,H). 
>Those models with mixed addressing modes (C,M) cause a problem because
>it is impossible for printf to differentiate between code and data
>pointers.

Kevin is correct.  The cited behavior is new in MSC V6.0, though
not noted in the "what's new in V6.0" document (such as it is).
I wish they had mentioned it; I consider it a significant
improvement, and had been continuing to pollute my code with
now-unnecessary workarounds.

To make the point concrete, the code

	int i, *ip = &i;
	printf("%d %d %p %d %d\n", 1, 2, (void *)ip, 3, 4);

gives the following results under various model/version
combinations:

		MSC V5.10			MSC V6.00

	small	1 2 0003:0D6E 4 2180		1 2 0D7E 3 4

	large	1 2 16EF:0F42 3 4		1 2 1D50:0E42 3 4

The erroneous result is illustrated by the small-model code
compiled with V5.10: %p expects a 32-bit far pointer, but a
16-bit near pointer is passed, so a following argument (3) is
consumed for the segment part, and the last %d receives garbage.
Under V6.00 in small model, %p correctly pops and prints only a
16-bit pointer (evidently only the offset part, which is
reasonable).  Under either compiler version, the large-model %p
behavior is as expected.

I hereby retract some of the bile I spewed against Microsoft in
my previous posting on this topic.  (I wonder how extensive the
compact and medium model problems to which Kevin refers are?  Is
there a note, buried somewhere in the fully-updated documentation
I don't have yet, to the effect that ANSI compliance is only
guaranteed if you avoid compact and medium models?  I can't test
them, because I can't afford the disk space to keep four memory-
model-specific copies of the run-time libraries around.)

This has gotten very PC-specific, so I've redirected followups to
comp.sys.ibm.pc.programmer .

                                            Steve Summit
                                            scs@adam.mit.edu

karl@haddock.ima.isc.com (Karl Heuer) (08/07/90)

In article <444@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>Those models with mixed addressing modes (C,M) cause a problem because
>it is impossible for printf to differentiate between code and data
>pointers.

No problem; the ANSI %p format is only intended to handle data pointers cast
to `void *'.  Function pointers, or uncast& data pointers, are beyond the
scope of this format specifier.

>Also, it seems to me that a program that tries to do anything significant
>with %p is probably not really very portable anyway.

Granted.

Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
________
& Of course one needn't cast an expression which is already `void *', or
  (because of the same-representation clause) `char *'.