Path: csiph.com!news.swapon.de!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Partial function types
Date: Tue, 21 May 2024 22:15:38 -0700
Organization: A noiseless patient Spider
Lines: 71
Message-ID: <86zfsiv345.fsf_-_@linuxsc.com>
References: <87v837kinv.fsf@nosuchdomain.example.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Date: Wed, 22 May 2024 07:15:40 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="ef527a1f0ace8b0bcb46bd1e68f4f6ae"; logging-data="1101574"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1836+8zWAgObh8Iz/9CA/ZNshaaSKf6tDg="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:NZS04Duul/kel8Qr1SoGtdD11l8= sha1:MljORq9QUtXpHPr6JFa5+nIQmMc=
Xref: csiph.com comp.lang.c:384814
[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 writes:
> wij 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.