Date: Mon, 24 Sep 2001 08:13:47 +1000 (EST) From: Bruce Evans <bde@zeta.org.au> To: Bakul Shah <bakul@bitblocks.com> Cc: Murray Stokely <murray@FreeBSD.org>, <cvs-committers@FreeBSD.org>, <cvs-all@FreeBSD.org> Subject: Re: cvs commit: src/usr.sbin/sysinstall command.c config.c Message-ID: <20010924074613.F18180-100000@delplex.bde.org> In-Reply-To: <200109231749.NAA01962@glatton.cnchost.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 23 Sep 2001, Bakul Shah wrote:
> > > Use '%p' when printing out the address of a function.
> > > sizeof(int) != sizeof(long)
> >
> > %p is for printing pointers of type "void *". It is unsuitable for
> > printing arbitrary pointers to objects. It is especially unsuitable
> > for printing pointers to functions.
>
> I have an old (1997) working draft of C9X which says
>
> 6.2.2.3 Pointers
>
> [#1] A pointer to void may be converted to or from a pointer
> to any incomplete or object type. A pointer to any
> incomplete or object type may be converted to a pointer to
> void and back again; the result shall compare equal to the
> original pointer.
>
> Since any object ptr may be converted to %p, you can do, e.g.
>
> printf("...%p...", ..., (void*)&some_function, ...);
>
> But you seem to be saying this is not be a valid conversion.
> Have things changed since then or is a function not
> considered an "object"? I would appreciate a C standard
> reference ( i.e. chapter and verse!) that shows this is
> invalid.
Functions aren't objects, and incomplete types aren't for functions.
Reference supplied by TenDRA C for (void *)&some_function:
"z.c", line 5: Error:
[ISO 6.3.4]: Can't convert function pointer 'int ( * ) ()' to non-function pointer 'void *'.
[ISO 6.3.4]: Can't perform this conversion using an explicit cast.
Quotes from c99 draft:
3.15
[#1] object
region of data storage in the execution environment, the
contents of which can represent values
6.2.5 Types
[#1] The meaning of a value stored in an object or returned
by a function is determined by the type of the expression
used to access it. (An identifier declared to be an object
is the simplest such expression; the type is specified in
the declaration of the identifier.) Types are partitioned
into object types (types that describe objects), function
types (types that describe functions), and incomplete types
(types that describe objects but lack information needed to
determine their sizes).
> At any rate %p is preferable to %x or %lx even if not
> properly pedantic. I have used machines with segmented
> address space (an NEC unix machine in mid80s though I forget
> the model number) where %p would give you <seg>:<addr> but %x
> or %lx would be wrong.
This is machine-dependent. Another example: for i386's in real mode,
pointers can be <seg>:<addr> or just <addr>. There are 4 memory
"models" corresponding to the 2 independent choices for function and
object pointers. %p doesn't work for large function pointers mixed
with small data pointers or vice versa. OTOH, %x or %lx (the one for
ints of the same size as the pointer being printed) does something
reasonable if not correct.
Bruce
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010924074613.F18180-100000>
