Interpretation of peculiar declarators?
David Michaels
david at lpi.liant.com
Thu May 9 09:46:21 AEST 1991
In article <679 at rosie.NeXT.COM> mself at 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 at lpi.liant.com)
Language Processors, Inc.
Framingham, Massachusetts
More information about the Comp.std.c
mailing list