Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c++ Subject: Re: Can someone please verify the execution trace of this? Date: Mon, 20 May 2024 19:31:37 -0700 Organization: None to speak of Lines: 90 Message-ID: <87r0dvki9i.fsf@nosuchdomain.example.com> References: <87v837kinv.fsf@nosuchdomain.example.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Tue, 21 May 2024 04:31:38 +0200 (CEST) Injection-Info: dont-email.me; posting-host="c8b9c4af0c1e718c0b80a50db3431e40"; logging-data="433846"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19sd9Ppa9NKqan5cwYQUWAu" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:qH9aM8pavYtD/gFFH2mynMm6ntY= sha1:ZwY3oUSWBxrKK3ZfWx/ZO8EAk+U= Bytes: 5228 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 C23 standard, not yet released, changes the semantics of empty > parentheses, causing the code to be invalid, but let's assume C17.) > > The function H is declared but not defined. That doesn't prevent > the code from being *compiled*, but it does prevent it from being > *linked* to produce an executable program. Perhaps a definition > of H has been presented in some other article, but I will not waste > my time hunting for it. > > Ignoring variadic functions like printf, every function call > must pass the appropriate number and types of arguments, matching > the parameters defined by the corresponding function definition. > (In some cases there can be implicit type conversions, but there > are no implicit conversions for arguments or parameters of function > pointer type.) If a correct *prototype* (a function declaration that > specifies the types of all parameters) is visible, this is enforced > at compile time; failing to do so is a *constraint violation*, > requiring a compile-time diagnostic. If no such prototype is > visible, violations of this rule need not be diagnosed, but result > in *undefined behavior*; the C standard says nothing about what > the program will do. > > 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. > > It's possible to rewrite the code to (a) avoid the use of old-style > function declarations and (b) avoids any undefined behavior -- > but without knowing or being able to guess just what the program > is supposed to do, I see no point in doing so. > > The main point is this: The function H is declared but never > defined, so it's impossible to create a running program from this > code, and impossible to guess what it's intended to do without more > information. I will not make any assumptions about how H is meant > to be defined or consult other posts to find a definition. I may or > may not follow this thread to see if any clarifications are posted. > > The code as presented is a valid C *translation unit*, but it is > not a valid *program*, and it has no behavior. My apologies, I did not notice this had been posted to comp.lang.c++ until just as I posted my followup. If I had noticed that, I probably wouldn't have posted at all. I'll try to pay better attention. C++ does not have old-style function declaration. Empty parentheses in a C++ function declaration or definition indicate that the function has no parameters. In C++, a pointer of type "ptr" can only point to a function with no parameters. The call "H(D, D)" passes the address of the function D (which has one parameter) to a parameter of type "ptr" (which requires a pointer to a function with no parameters). That's an error. The code is ill-formed in C++. And of course the lack of any definition of H is another problem that makes it difficult or impossible to correct the C++ errors and produce a valid program. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com void Void(void) { Void(); } /* The recursive call of the void */