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.