From: scs@adam.mit.edu (Steve Summit)
Subject: Re: question about duplicate declarations
Summary: parameter redefinition illegal
Organization: none, at the moment
Date: Fri, 16 Oct 1992 17:06:08 GMT

In article <1992Oct13.211753.15516@phri.nyu.edu>, Roy Smith (roy@mchip00.med.nyu.edu) writes:
> foo (int x)
> {
> 	int x;
> 
> What should you expect a compiler to do?  In my case, the second "int x" was
> a mistake; it shouldn't have been there at all.  Apparantly, though, the
> compiler treated it as if it was simply a declaration of a new x inside a
> local block.  Is that the reasonable thing to do?  Should it have issued
> some sort of warning about duplicate declarations?

In this case: no, it is not a reasonable thing to do; and yes,
the compiler should have issued a warning or error.

In article <1992Oct16.024907.28552@CSD-NewsHost.Stanford.EDU>, one of Whizzo's finest delicacies (amorgan@csd-d-3.Stanford.EDU) writes:
>> What should you expect a compiler to do?  
> Exactly what it did.  Compile without error.
>> ...Should it have issued
>> some sort of warning about duplicate declarations?
> It doesn't have to.

Not in the old days; but in the old days, Roy's fragment would
have been written

	foo(x)
	int x;
	{
		int x;

In pre-ANSI ("Classic") C, a local variable could indeed mask a
parameter, although lint justifiably warned about the occurrence.

In article <1992Oct16.125234.4096@peanuts.informatik.uni-tuebingen.de>, Till Bubeck (bubeck@peanuts.informatik.uni-tuebingen.de)  writes:
> I think it should result in an error message...But no one's interested in my
> opinion...

Don't be so hard on yourself :-) !  The ANSI C Standard states
that function formal parameters are declared at block scope, not
in some enclosing parameter scope, so the fragment should
definitely elicit an error.  (Under an ANSI compiler, the error
results whether the function definition is old-style or prototype
style.)

	If the declarator... that declares the identifier
	appears... within the lit of parameter declarations in a
	function definition, the identifier has block scope,
	which terminates at the } that closes the associated block.
	[ANSI X3.159 sec. 3.1.2.1 p. 21 lines 31-32]

	A parameter is in effect declared at the head of the
	compound statement that constitutes the function body,
	and therefore may not be redeclared in the function body
	(except in an enclosed block).
	[sec. 3.7.1 p. 83 footnote 81]

	Some current implementations permit an argument to be
	masked by a declaration of the same identifier in the
	outermost block of a function.  This usage is almost
	always an erroneous attempt by a novice C programmer to
	declare the argument; it is rarely the result of a
	deliberate attempt to render the argument unreachable.
	The committee decided, therefore, that arguments are
	effectively declared in the outermost block, and hence
	cannot be quietly redeclared in that block.
	[Rationale, section 3.7.1, p. 61]

I'm a bit surprised that the Rationale doesn't call this out as a
"Quiet Change" (it does so qualify a few even more obscure changes).
I think I remember one (working) program of mine which happened
to declare a local variable x which masked a parameter x which
happened not to be used, but it was clearly aberrant (I fixed it
when lint complained about it), so I'm certainly not lamenting
this decision by ANSI.

					Steve Summit
					scs@adam.mit.edu
Newsgroups: comp.lang.c