unhd (Anthony Lapadula) (09/15/90)
While implementing a (hopefully soon-to-be-) ANSI-compliant compiler,
we came across the following problem. Given
typedef int INT;
typedef char CHAR;
which of the following are legal?
main()
{
unsigned INT foo1;
extern INT foo2;
extern INT (CHAR);
}
I've read section 3.5.6 of the standard, but with no luck deciding the issue.
Harbison and Steel (1987, p. 116) state that the declaration of ``foo1''
would be illegal, but the declaration of ``foo2'' would be legal.
This seems reasonable.
What about the third declaration? Seems that it would declare a (new)
variable CHAR to be of type ``int'' and with storage class ``external''.
Is this right? Is CHAR a candidate to be a variable because it may override
its typedef'ed meaning from the outer block?
It was discussed here (last month?) that implementing typedef-names is
done as follows: lexer get the candidate identifier, asks the symbol table
if it is currently a typedef-name, and returns, e.g., TYPEDEF or IDENTIFIER
to the grammar.
Doesn't the lexer have to know more? In my third example, the
lexer needs to know that CHAR is a candidate variable, even though it
is currently a typedef-name. How is this implemented?
As an aside, gcc 1.37.1 rejects my first example
unsigned INT foo1;
but accepts
INT unsigned foo1;
Any takers to explain this?
-- Anthony (uunet!unhd!al, al@unh.edu) Lapadula
// Wanted: catchy .sig.
eyal@echo.canberra.edu.au (Eyal Lebedinsky) (09/16/90)
In article <1990Sep14.213822.4828@uunet!unhd> al@uunet!unhd (Anthony Lapadula) writes: >While implementing a (hopefully soon-to-be-) ANSI-compliant compiler, >we came across the following problem. Given [...] > unsigned INT foo1; 3.5.2 clearly states which type-specifier lists are allowed, and this is not one of those. > extern INT foo2; This is a storage-class-specifier followed by a type-specifier which is ok for 3.5. > extern INT (CHAR); typedefs and variables share a common namespace to CHAR will hide the external one. [...] >Doesn't the lexer have to know more? In my third example, the >lexer needs to know that CHAR is a candidate variable, even though it >is currently a typedef-name. How is this implemented? I found it necessary NOT to have the lexer make the decision for the same reason. > >-- Anthony (uunet!unhd!al, al@unh.edu) Lapadula I am using the May/88 Draft. Regards Eyal -- Regards Eyal
henry@zoo.toronto.edu (Henry Spencer) (09/18/90)
In article <1990Sep14.213822.4828@uunet!unhd> al@uunet!unhd (Anthony Lapadula) writes: > typedef int INT; > typedef char CHAR; > ... { ... > unsigned INT foo1; > extern INT foo2; > extern INT (CHAR); The 3.5.2 constraints outlaw foo1, but the other two declarations are legal. Typedef names follow block-structured scope rules and can be hidden by variable declarations in inner blocks. Your grammar actually *has* to include the 3.5.2 constraints to some degree; you can't leave them until later, because typedef unsigned U; ... { ... short U = 2; /* !!! */ is perfectly legal C. Typedef names don't mix with other type specifiers, so `!!!' is a perfectly legal declaration of a variable named `U' with type `signed short int' which is initialized to 2. Barf. >... lexer get the candidate identifier, asks the symbol table >if it is currently a typedef-name, and returns, e.g., TYPEDEF or IDENTIFIER >to the grammar. > >Doesn't the lexer have to know more? In my third example, the >lexer needs to know that CHAR is a candidate variable, even though it >is currently a typedef-name. How is this implemented? The lexer really can't know, in these cases, what's wanted. What you have to do is mung your parser so that (a) it knows that typedef names don't mix with the other specifiers like `unsigned' and (b) in some (not all!) places it takes typedef names as alternatives to identifiers, with later processing treating them as equivalent. There is just no other way to cope with the `!!!' example. >As an aside, gcc 1.37.1 rejects my first example > unsigned INT foo1; >but accepts > INT unsigned foo1; Sounds like a bug. (Although the gcc folks have a tendency to call such things "features" any time they don't like what the standard says.) -- TCP/IP: handling tomorrow's loads today| Henry Spencer at U of Toronto Zoology OSI: handling yesterday's loads someday| henry@zoo.toronto.edu utzoo!henry