peter@sugar.UUCP (Peter da Silva) (07/31/87)
According to an article on ANSI 'C' in Dr Dobb's Journal, a prototype
with a fixed number of arguments means the routine may be called without
unwinding the stack on return... the assumption being that the called
routine popped its arguments with a "RET N" type instruction.
It then adds that if no prototype is provided, the function may be
assumed to have a fixed number of arguments.
This is dangerous, in that it breaks existing code. Example:
/* no #includes */
exec_system(s)
char *s;
{
execl("/bin/sh", "sh", "-c", s, 0);
printf("Shell not found.\n");
return 0;
}
Execl will be called as a routine that expects a fixed number of args.
The stack will not be unwound. The routine will return to (probably) the
address of the string "/bin/sh", leading to unusual results.
On the other hand, if they don't make that assumption, any call you make
without prototypes will lead to the stack being unwound twice.
I don't know if there's an answer... perhaps this could be made an optional
and defeatable extension?
--
-- Peter da Silva `-_-' ...!seismo!soma!uhnix1!sugar!peter (I said, NO PHOTOS!)
golde@uw-beaver.UUCP (Helmut Golde) (08/06/87)
In article <449@sugar.UUCP> peter@sugar.UUCP (Peter da Silva) writes: >According to an article on ANSI 'C' in Dr Dobb's Journal, a prototype >with a fixed number of arguments means the routine may be called without >unwinding the stack on return... the assumption being that the called >routine popped its arguments with a "RET N" type instruction. > >It then adds that if no prototype is provided, the function may be >assumed to have a fixed number of arguments. This is correct, but the key word in the paragraph is "may". Probably most compilers will continue to do things the old way, with the same calling conventions for fixed length and variable length argument lists. However, on some machines it is much more efficient to to use a calling sequence which only supports fixed length variable lists, so this is why ANSI allows different calling sequences for fixed and variable length argument lists. The moral (and ANSI makes this very clear): all calls to functions which take a variable number of arguments must be made in the presence of a prototype. Your program is *non-portable* otherwise. In general, you are just plain dumb if you write any program in which *any* function calls are made without an applicable prototype or include file. They don't take much time to put in, they may make your program run faster, and you're sure to save debugging time. (I think almost every program over 300 lines I have written I have been saved from a type screw-up by prototypes). >I don't know if there's an answer... perhaps this could be made an optional >and defeatable extension? It *is* optional, as I stated above. Some compilers may even have a switch which allows you to do it both ways (Microsoft C for example). Obviously in such a case a provision must be made that a different library will be used or that library calls are always made the same way regardless of the switch. --Peter ]
henry@utzoo.UUCP (Henry Spencer) (08/06/87)
> According to an article on ANSI 'C' in Dr Dobb's Journal, a prototype > with a fixed number of arguments means the routine may be called without > unwinding the stack on return... the assumption being that the called > routine popped its arguments with a "RET N" type instruction. Sorry, basically wrong. Unless ANSI has done something terrible since the draft I've got (1 Oct 1986, the public-comment draft), functions are required to behave properly, subject to certain restrictions on argument types, even if a function prototype is visible at definition but not at call, or vice-versa. This means, pretty much, that the presence or absence of a prototype can't make a difference in something as basic as who pops the stack. > It then adds that if no prototype is provided, the function may be > assumed to have a fixed number of arguments. This is simply wrong: no prototype means no assumptions. -- Support sustained spaceflight: fight | Henry Spencer @ U of Toronto Zoology the soi-disant "Planetary Society"! | {allegra,ihnp4,decvax,utai}!utzoo!henry
gwyn@brl-smoke.ARPA (Doug Gwyn ) (08/07/87)
In article <8383@utzoo.UUCP> henry@utzoo.UUCP (Henry Spencer) writes: >> It then adds that if no prototype is provided, the function may be >> assumed to have a fixed number of arguments. >This is simply wrong: no prototype means no assumptions. Perhaps what the article meant was that the <stdarg.h> facility cannot be used in the absence of a (,...) style function prototype. That is indeed true.
karl@haddock.ISC.COM (Karl Heuer) (08/07/87)
In article <8383@utzoo.UUCP> henry@utzoo.UUCP (Henry Spencer) writes: >> It then adds that if no prototype is provided, the function may be >> assumed to have a fixed number of arguments. > >This is simply wrong: no prototype means no assumptions. "A.6.2 Undefined behavior: ... A function that accepts a variable number of arguments is called, but no prototype declarator with the ellipsis notation is in scope." [Oct86 dpANS] In other words, a variadic function must have a prototype. This implies that a function called without a prototype in scope may be assumed to have a fixed number of arguments. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
henry@utzoo.UUCP (Henry Spencer) (08/16/87)
> "A.6.2 Undefined behavior: ... A function that accepts a variable number of > arguments is called, but no prototype declarator with the ellipsis notation > is in scope." [Oct86 dpANS] > > In other words, a variadic function must have a prototype. This implies that > a function called without a prototype in scope may be assumed to have a fixed > number of arguments. Correct -- I think -- but only after considerable study. A.6.2 is in the appendix, thus is *not* part of the standard. Careful study of 3.3.2.2 *suggests* the truth of the A.6.2 note, but I wouldn't want to have to try to prove it rigorously from the current wording. 3.3.2.2 observes: "If no function prototype declarator is in scope... [and] the number of arguments does not agree with the number of formal parameters, the behavior is undefined." So far so good... but what *is* the "number of formal parameters" for a variadic function?? 3.5.3.3, Function Declarators, gives vague and inconsistent hints but no definitive guidance. Unless I have missed some clear statement somewhere else, I think wording changes are in order -- the A.6.2 statement is not unambiguously supported by the standard proper. The simplest fix would be to add the A.6.2 statement quoted above somewhere around line 8 of 3.3.2.2 (draft of 1 Oct 1986). [Doug, you listening?] -- Support sustained spaceflight: fight | Henry Spencer @ U of Toronto Zoology the soi-disant "Planetary Society"! | {allegra,ihnp4,decvax,utai}!utzoo!henry