Skip site navigation (1)Skip section navigation (2)
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>