• Partial function types

    From Tim Rentsch@21:1/5 to Keith Thompson on Tue May 21 22:15:38 2024
    [I am responding to a post in comp.lang.c++, but the subject is
    C, so the response is directed to comp.lang.c.]

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    wij <wyniijj5@gmail.com> writes:
    [...]

    typedef int (*ptr)(); // ptr is pointer to int function
    int H(ptr x, ptr y);
    int D(ptr x)
    {
    int Halt_Status = H(x, x);
    if (Halt_Status)
    HERE: goto HERE;
    return Halt_Status;
    }

    int main()
    {
    H(D,D);
    return 0;
    }

    The code above does not compile:

    Yes, it does (as you acknowledge in a later post).

    This:
    typedef int (*ptr)();
    defines "ptr" as an alias for a type that can be described in English
    as "pointer to function returning int". The empty parentheses
    indicate that the function takes an unspecified but fixed number
    and type(s) of arguments; this is an old-style declaration. [...]

    The function H is declared but not defined. [...]

    I'll note that the code (declares and) defines the function D,
    but never calls it. The address of D is passed to H, but without
    a definition of H we can't guess what it does with that address.

    All good up to this point.

    It's possible to rewrite the code to (a) avoid the use of old-style
    function declarations [...]

    Not without radically altering the code. Because D is passed
    as an argument to H, and because of how H and D are declared,
    the type of (the address of) D has to match the type of D's
    first parameter. It isn't possible to do this in C without
    resorting to a partial function type somewhere (because the
    type of D is infinitely recursive).

    There are other ways to work around this problem, for example
    involving having a pointer-to-function member in a struct,
    but that would entail changing either the declarations or
    the call of H() with D as an argument, which seems to be
    stretching the bounds of "rewrite the code".

    The code as presented is a valid C *translation unit*, but it
    is not a valid *program*,

    It might be better to say it's a valid partial program, but not
    a complete program.

    and it has no behavior.

    It doesn't have behavior in the sense that it doesn't do anything.
    It does have behavior in the sense that the C standard prescribes
    a meaning for the declarations and definitions given. I believe
    the C standard uses the term "behavior" in both of those senses.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)