Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: calling argumentless function with argument Date: Fri, 04 Jan 2019 10:55:12 -0800 Organization: None to speak of Lines: 58 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader01.eternal-september.org; posting-host="51f48b5f140b1e2207d905a0bcd16c92"; logging-data="26672"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+aW73+uJVGhn3udb4JKs0+" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:cOisrPH3v8LWLHFoA1Ll8Mzw4FA= sha1:iQ0peW5o1yfgY4QZaveTUL8Q1Xw= Xref: csiph.com comp.lang.c:139426 Bart writes: > On 04/01/2019 16:34, David Brown wrote: >> On 04/01/2019 17:04, Jens Thoms Toerring wrote: >>> is there anything to worry about if one calls a function >>> that takes no arguments with an argument like this? >>> >>> void foo(void); // defined somewhere else >>> >>> int main(void) >>> { >>> void (*p)() = foo; >>> p(4); >>> } >> >> It is undefined behaviour. It is likely to "work" in most cases (the >> argument would be put onto the stack or into a register, and then >> ignored by the called function). >> >> However, if the compiler is using a "callee cleanup" calling convention >> rather than "caller cleanup", you'll be in trouble. "Caller cleanup" is >> the traditional for C, especially on *nix systems. But "callee cleanup" >> is used with a variety of calling conventions on Windows (like MS >> fastcall, stdcall, etc.). If your call requires putting anything on the >> stack instead of just registers, you'll get in trouble. > > If it's C calling C, then I think caller clean-up is always used (from > what I've seen on Windows anyway), otherwise it would be harder to > implement variadic functions such as printf. It may well be the case that most or all C compilers use caller cleanup, at least partly for historical reasons. It makes it possible, for example, to call printf without a correct declaration in scope. (Pre-ANSI C didn't have prototypes, so a compiler wouldn't necessarily even know that printf is variadic.) But the standard is carefully worded to permit either caller cleanup or callee cleanup. Calling a variadic function with no visible prototype (or with a prototype that doesn't match the definition) has undefined behavior, which allows a compiler to treat variadic functions specially. [...] >> In what circumstances would it be useful? > > You have a function pointer intended to call a range of functions some > of which have a parameter, and some don't. But you want to use the same, > consistent function pointer type and the same call code. Then you want > those functions without a parameter to ignore it. I can imagine that being useful -- but C doesn't support it with defined behavior. Just be aware of the risk that some compiler could break your code. -- Keith Thompson (The_Other_Keith) kst@mib.org Will write code for food. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"