Re: typedef Used to Cast Function Pointers

From: Dave Thompson (david.thompson1_at_worldnet.att.net)
Date: 12/12/03


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



Relevant Pages

  • Re: Why is this not an error in Visual C?
    ... int foo ... What we're looking for to describe MSVC as broken is a constraint ... involve declarations of incompatible types. ... compatibility and of a composite type, ...
    (comp.lang.c)
  • Re: Why is this not an error in Visual C?
    ... says that when an old-style function definition is processed, ... That is, I think, `int fint x; ... Concerning the compatibility of function ... All declarations in the same scope that refer to the same object or function ...
    (comp.lang.c)
  • Re: Why is this not an error in Visual C?
    ... says that when an old-style function definition is processed, ... That is, I think, `int fint x; ... Concerning the compatibility of function ... All declarations in the same scope that refer to the same object or function ...
    (comp.lang.c)
  • Re: const and array of array (of array ...)
    ... int main ... I understand arrays 'decay' into a pointer to their first element when ... qualifiers of the type pointed to by the right. ... With the correction that actual compatibility is not the issue, ...
    (comp.lang.c)
  • Re: Why is this not an error in Visual C?
    ... extern int foo; ... involve declarations of incompatible types. ... This is not a constraint so there is no requirement on an ... type compatibility, with no exception for functions that are not ...
    (comp.lang.c)