Rick 'Transputer' Stein@dhw68k.cts.com (Rick 'Transputer' Stein) (10/14/88)
I wonder if any of you gurus can comment on the following fragment of code output from lex: The function yyback has two arguments, but only one is typed in argument the list. Why does my C compiler or lint, for that matter, not complain? yyback(p,m) int *p; { if (p==0)return(0); while(*p) { if ( *p++ == 0 )return(1); } return(0); } I've compiled this fragment along with the body of lex.yy.c on many machines and compilers (SGI/4D, HP9000, SUN/4, Inmos transputers with 3L,MSC 4.0, etc) and no errors have been generated. Are undeclared function arguments auto casted to pointers? Thanks in advance. +--------------------------+---------------------------------------+ | Rick 'Transputer' Stein | uucp: ...{felix, zardoz}!dhw68k!stein | | "Goddam digital confuser | MaBellnet: 714-786-7794 (H) | | technology..." | 714-540-8900 (W) | | Disclaimer: These opinions are mine, not my employer's. | +--------------------------+-------------------------------------- +
rkl1@hound.UUCP (K.LAUX) (10/17/88)
YYBACK (i, m)
int i;
{
...
}
The reason that 'm' was not declared was that the body of the
function did not reference the variable at all *AND* it was the last
parameter in the formal argument list. Since arguments are pushed on
the stack from *right* to *left*, there was no need to know its size.
It would be a different case if:
YYBACK (i, m, n)
and only i and n were referenced because now the compiler would
*have* to know the size of m in order to correctly reference n on the stack.
--rkl
psrc@poseidon.ATT.COM (Paul S. R. Chisholm) (10/17/88)
<"He seemed like such a nice man . . . and then he turned out to be a writer!"> In article <13168@dhw68k.cts.com>, Rick 'Transputer' Stein@dhw68k.cts.com (Rick 'Transputer' Stein) asks why the following compiles cleanly: yyback(p,m) int *p; { if (p==0)return(0); while(*p) { if ( *p++ == 0 )return(1); } return(0); } > I've compiled this fragment along with the body of lex.yy.c on many > machines and compilers (SGI/4D, HP9000, SUN/4, Inmos transputers with > 3L,MSC 4.0, etc) and no errors have been generated. Are undeclared > function arguments auto casted to pointers? >Rick 'Transputer' Stein, {felix, zardoz}!dhw68k!stein According to K&R 1st ed. (p. 205), "Any [parameter-list] identifiers whose type is not given are taken to be int." p is declared and used as a pointer. m is implicitly declared an int, and not used at all! (But lint should have complained about m as an unused argument.) Paul S. R. Chisholm, psrc@poseidon.att.com (formerly psc@lznv.att.com) AT&T Bell Laboratories, att!poseidon!psrc, AT&T Mail !psrchisholm I'm not speaking for the company, I'm just speaking my mind.
jfh@rpp386.Dallas.TX.US (The Beach Bum) (10/19/88)
In article <2686@hound.UUCP> rkl1@hound.UUCP (K.LAUX) writes: > The reason that 'm' was not declared was that the body of the >function did not reference the variable at all *AND* it was the last >parameter in the formal argument list. Since arguments are pushed on >the stack from *right* to *left*, there was no need to know its size. This is not portable, relevant, or correct. The formal argument `m' has a default type of `m', hence the type and size are known, as a matter of fact. Regardless of `m' being referenced, the type will always default to `int'. The order of arguments on the stack, or even the existance of a stack, is not an issue which is addressed by the language specification. There exists hardware in which a function with two arguments will pass the actual parameters are passed in registers or pre-allocated regions of memory. > It would be a different case if: > > YYBACK (i, m, n) > > and only i and n were referenced because now the compiler would >*have* to know the size of m in order to correctly reference n on the stack. This would be correct if the size of `m' were not set by default to be sizeof (int). If the call were YYBACK (i, m, n) int i; struct foo m; int n; and the size of `m' weren't known, THEN it MIGHT be an issue. However, only structure pointers do not require the size of the underlying structure to be known. Since `m' in this case is not a pointer, this exception does not apply and the above example is illegal. C provides that undeclared formal parameters default to type `int'. This may not be a wonderful idea, but it does cover this situation. -- John F. Haugh II +----Make believe quote of the week---- VoiceNet: (214) 250-3311 Data: -6272 | Nancy Reagan on Richard Stallman: InterNet: jfh@rpp386.Dallas.TX.US | "Just say `Gno'" UucpNet : <backbone>!killer!rpp386!jfh +--------------------------------------
guy@auspex.UUCP (Guy Harris) (10/19/88)
>Since arguments are pushed on the stack from *right* to *left*,
"Are pushed" in some implementations, anyway; there is no requirement in
any language spec that says it has to be done that way.
rkl1@hound.UUCP (K.LAUX) (10/20/88)
In article <8058@rpp386.Dallas.TX.US>, jfh@rpp386.Dallas.TX.US (The Beach Bum) writes: > In article <2686@hound.UUCP> rkl1@hound.UUCP (K.LAUX) writes: > > The reason that 'm' was not declared was that the body of the > >function did not reference the variable at all *AND* it was the last > >parameter in the formal argument list. Since arguments are pushed on > >the stack from *right* to *left*, there was no need to know its size. > > This is not portable, relevant, or correct. > > The formal argument `m' has a default type of `m', hence the type and > size are known, as a matter of fact. Regardless of `m' being referenced, > the type will always default to `int'. > > The order of arguments on the stack, or even the existance of a stack, > is not an issue which is addressed by the language specification. There > exists hardware in which a function with two arguments will pass the > actual parameters are passed in registers or pre-allocated regions of > memory. > > > It would be a different case if: > > > > YYBACK (i, m, n) > > > > and only i and n were referenced because now the compiler would > >*have* to know the size of m in order to correctly reference n on the stack. > > This would be correct if the size of `m' were not set by default to be > sizeof (int). If the call were > > YYBACK (i, m, n) > int i; > struct foo m; > int n; > > and the size of `m' weren't known, THEN it MIGHT be an issue. However, > only structure pointers do not require the size of the underlying structure > to be known. Since `m' in this case is not a pointer, this exception does > not apply and the above example is illegal. You're absolutely right about non-declared variables defaulting to 'int'. It's also true that stacks are not part of the language specification. However, its not uncommon for compilers to use a stack and to push arguments from right to left (MSC, AT&T, DEC...) I find that I often need to check the assembly language generated to see just what's going on (usually I'm reworking already written code) and, upon reflection of writing the above, I can see I was definitely influenced by my experiences (...why is it *I* always have to find those subtle compiler bugs the hard way...oh, well). --rkl