Path: utzoo!utgpu!utstat!jarvis.csri.toronto.edu!mailrus!ames!hc!lll-winken!uunet!datapg!com50!jhereg!mark From: mark@jhereg.Jhereg.MN.ORG (Mark H. Colburn) Newsgroups: comp.lang.c Subject: Re: %p and different pointer representations Message-ID: <591@jhereg.Jhereg.MN.ORG> Date: 25 Feb 89 21:50:23 GMT References: <9382@bloom-beacon.MIT.EDU> <234@mstan.Morgan.COM> Reply-To: mark@jhereg.MN.ORG (Mark H. Colburn) Organization: Minnetech Consulting, Inc., St. Paul, MN Lines: 82 In article <234@mstan.Morgan.COM> dff@Morgan.COM (Daniel F. Fisher) writes: >Consider a hosted C implementation in which different pointers >have different representations, i.e. (char *) is different from >(int *) is different from (int (*)()), etc. My question is > >To what type should a pointer argument be cast when passing it to >fprintf() for printing using the %p conversion specifier? > >In view of the following two examples, I don't see that there is >a single correct answer that will work in all architectures. And >since %p is part of dANS C, I assume that the answer must be the >same for every pointer in every conforming hosted implementation. Casting the pointer to (void *) is supposed to do what you want. The pANS says that a void pointer is large enough to handle any pointer type (ss 3.2.2.3), much like "char *" was supposed to handle any pointer type in old K&R. The documentation for scanf (ss 4.9.6.2) and printf (ss 4.9.6.1), also say that the %p is expected to be a void pointer. >First Example: In an IBM-PC implementation with small-data, >large-code, the data pointers (int *), (char *), etc. are all 16 >bits., but function pointers (int (*)()), etc. are all 32 bits. >So if I wish to print a function pointer, I cannot cast it to a >data pointer without losing information. One the other hand, >since the type cast used for both function pointers and data >pointers should be the same, I must cast all data pointers to >something that is as wide as a function pointer. Casting the pointer to "void *" is not supposed to lose information for any conforming implementation. On the IBM-PC, using Turbo C 2.0, printf("main %p\n", main) will print out a segment:offset address like so: main 252B:000C It does this for all memory models. (I just checked). The address which is printed corresponds to the link map which I generated as well. I checked this for functions, pointers to functions, static and global data in all memory models. The results were always correct. A side note here: the %p parameter prints the result out in an implementation defined format, so the above example is what you get on the IBM-PC, while on a SUN you may get: main 0x00678A The reason, of course, is to allow the implementation to print the address out in whatever format is most usefull for the particular architecture or implementation. >Second Example: In an implementation on an architecture that is >NOT byte addressable, int pointers and function pointers will be >word addresses and character pointers will be wider to contain >both a word address and a byte offset. So if I wish to print a >character pointer, I cannot cast it to an int pointer or function >pointer without losing information. One the other hand, since the >type cast used for all pointers must be the same, I must cast int >pointers and function pointers to something as wide as a character >pointer. The void pointer is gauranteed to be wide enough by the pANS. If it is not able to handle this example, then you should have a serious chat with your compiler vendor. >So in the first example, I want to cast everything to be as wide >as a function pointer and in the second, I want to cast everything >to be as wide as a character pointer (which is wider than a function >pointer). What's a programmer to do? Now if someone wants to tell >me that I should cast to (void *) because it is guaranteed to be at >least as wide as any pointer type in the implementation, then I will >say, "Thank you very much", "Wonderful", "Hooray for void star" and >"Gee, I didn't know that". Fair enough, now you do. :-) -- Mark H. Colburn "Look into a child's eye; Minnetech Consulting, Inc. there's no hate and there's no lie; mark@jhereg.mn.org there's no black and there's no white."