🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #2862

Re: Interpretation of peculiar declarators?

#2862
From: David Michaels
Date: Wed, 08 May 1991 23:46
82 lines
3424 bytes
In article <679@rosie.NeXT.COM> mself@next.com writes:

> I am trying to determine whether the following program is in error:
>
>	typedef int t;
>	void foo (void) {
>	  t t, x;
>	}
>
> I believe this ought to declare t and x to be of type int, since I don't
> believe that the fact that t is re-declared as a variable instead of a
> typedef  in the first declarator should affect the interpretation of the
> identifier t in the type-specifier for the second declarator (since the
> type-specifier is lexcically before the redefinition).

You're right, "t t, x;" is equivalent to "int t, x;".

> ANSI is quite specific that the scope of an identifier begins "just after
> the completion of its declarator" (3.1.2.1), and there is nothing to
> indicate that the identifiers in the type-specifier may be re-interpreted
> at each declarator.

Yep.

> An even more complicated case is this:
>
>	t t = 1, x = t;
>
> In this case I believe that this is exactly equivalent to
>
>	int t = 1, x = t;

Right again, they are equivalent.  This also might be of interest:

	const x;        /* ok -- same as const int x; */
	typedef int t;
	f () {
	     const t;   /* error -- no declarator name (i.e. const int;) */
	}
	g () {
	     const *t;  /* error -- technically, but ... */
	}

ANSI-C (3.5.6) says that if a typedef name is redeclared in an inner scope
(or as a struct/union member in the same or inner scope), the type specifiers
shall not be omitted.  This constitutes what someone coined as the "maximum
munch" rule (in C++ this rule is achieved by saying that the longest sequence
of declaration specifiers that could possibly be a type name is taken as the
declaration specifiers of a declaration).  The second error case is interesting
in that according to ANSI-C it is illegal, even though it is clear what is
meant, and the compiler has to go out of its way to generate a diagnostic.
Here's another one:

	typedef int t;
	f () {
	     const t (t (t (t (t))));
	}

This mess turns out to be a legal declaration equivalent to:

	const int t (int (int (int)));

I.e. a function "t" returning a "const int" and taking one parameter of
type [pointer to] function returning "int" and taking one parameter of type
[pointer to] function returning "int" and taking one parameter of type "int".

> If all of this speculation is true, then it puts some fairly strong 
> constraints on the implementation of compilers.  A compiler must look
> up any type name in the type-specifier only once (before processing
> any of the declarators), and it must enter the newly declared identifiers
> into the symbol table before processing subsequent declarators.

Exactly.  It turns out that it's not all that
difficult to get it straight; just a little tricky.

> Can anyone clear this up?

Sounds like you've got it all cleared up yourself.

				-- David Michaels (david@lpi.liant.com)
				   Language Processors, Inc.
				   Framingham, Massachusetts
Technical Details
Message-ID: <1991May8.234621.14067@lpi.liant.com>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!sdd.hp.com!spool.mu.edu!uunet!lpi.liant.com!david
References: <679@rosie.NeXT.COM>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!sdd.hp.com!spool.mu.edu!uunet!lpi.liant.com!david
From: david@lpi.liant.com (David Michaels)
Newsgroups: comp.std.c
Subject: Re: Interpretation of peculiar declarators?
Message-ID: <1991May8.234621.14067@lpi.liant.com>
Date: 8 May 91 23:46:21 GMT
References: <679@rosie.NeXT.COM>
Organization: Language Processors Inc., Framingham MA
Lines: 82