[comp.lang.c] Problem with either ANSI 'C' or Dr Dobbs Journal.

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