Re: typedef Used to Cast Function Pointers
From: Dave Thompson (david.thompson1_at_worldnet.att.net)
Date: 12/12/03
- Next message: Dave Thompson: "Re: a dumb strcat question"
- Previous message: Dave Thompson: "Re: Is C99 the final C? (some suggestions)"
- In reply to: Kevin Goodsell: "Re: typedef Used to Cast Function Pointers"
- Next in thread: Dave Thompson: "Re: typedef Used to Cast Function Pointers"
- Reply: Dave Thompson: "Re: typedef Used to Cast Function Pointers"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Fri, 12 Dec 2003 22:04:55 GMT
On Sun, 07 Dec 2003 22:39:01 GMT, Kevin Goodsell
<usenet1.spamfree.fusion@neverbox.com> wrote:
> Al Bowers wrote:
>
> >
> > The Standard explicitly calls it Undefined Behavior.
> >
> > From 6.3.2.3.8
> > "A pointer to a function of one type may be converted to
> > a pointer to a function of another type and back again;
> > the result shall compare equal to the original pointer.
> > If a converted pointer is used to call a function whose
> > type is not compatible with the pointed-to type, the
> > behavior is undefined."
> >
> >
>
> Question: In what ways could the function types be different, and still
> be compatible? I'm guessing it's safe if the conversion adds const
> and/or volatile qualifiers to some parameters. Could you replace a void*
> parameter with a char* parameter? A signed integer with an unsigned
> integer? What if the real function returns a value, but the pointer it's
> called through is to a void function type?
>
Two *prototyped* function types are compatible (only) if corresponding
parameters are compatible ignoring top-level qualification and after
"adjustment" to pointer of (declared) array or function parameters,
and both or neither end with ellipsis (variadic). void* and char* are
not compatible according to the type rules, although they are required
to have the same representation and so substituting them will work in
practice unless the implementation is odd (or perverse) enough to pass
them differently, and the same for corresponding signed and unsigned
integers. Including plain/signed/unsigned char, and pointers thereto.
An incomplete or "forward declared" struct or union is compatible with
the completed type, and (nearly) identically declared such types or
enums in different t.u.s are compatible although formally they are not
the same type. An enum is compatible with an implementation-defined
integer type, usually int. Array of unspecified (or in C99 VLA) bound
is compatible (at compile time) with array of fixed bound. I think
that's all the freedom you officially have.
The more complicated cases are compatibility between or with
unprototyped function types, e.g.:
int foo (int x, double y);
int foo (x, y) short x; float y; { blah blah }
are compatible, and a pointer to unspecified-args function:
int (*ptr)() = foo;
can be silently converted from any function pointer, but can correctly
be used to call only a function with no arguments (and returning int).
For unprototyped definitions, the void*-char* and signed-unsigned
cases are permitted in 6.5.2.2, which is more detailed than 6.3.3.8.
Both prototyped and unprototyped declarations (and definitions) of a
function do define the return type, and (so) function types with
different return types are never compatible.
- David.Thompson1 at worldnet.att.net
- Next message: Dave Thompson: "Re: a dumb strcat question"
- Previous message: Dave Thompson: "Re: Is C99 the final C? (some suggestions)"
- In reply to: Kevin Goodsell: "Re: typedef Used to Cast Function Pointers"
- Next in thread: Dave Thompson: "Re: typedef Used to Cast Function Pointers"
- Reply: Dave Thompson: "Re: typedef Used to Cast Function Pointers"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|