Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site mit-eddie.UUCP Path: utzoo!linus!security!genrad!mit-eddie!smh From: smh@mit-eddie.UUCP (Steven M. Haflich) Newsgroups: net.lang.c Subject: Re: typedef in c Message-ID: <1063@mit-eddie.UUCP> Date: Sun, 18-Dec-83 01:36:39 EST Article-I.D.: mit-eddi.1063 Posted: Sun Dec 18 01:36:39 1983 Date-Received: Sun, 18-Dec-83 23:40:28 EST References: <319@aecom.UUCP> Organization: MIT, Cambridge, MA Lines: 67 Jeremy Sanders asks why the following produces compilation errors: typedef struct { newtyp *member; } newtyp; Quite simply, newtyp does not become a legitimate type attribute until after the entire declaration statement has been processed. C is a one-pass compiler, and has no way of determining attributes from declarations occurring `later' in the source code. The problem is essentially the same as causes the following to be flagged with an `identifier redeclared' error: x = foo(); ... float foo() { ... } Compilers for languages such as PL1, which place no restriction on the ordering of indentifier declaration and use, necessarily make multiple passes through the source code. Incidentally, typedef occupies a very special place in the C language: Suppose you want to write some sort of preprocessor which parses but does not compile C source code. Assume this preprocessor nevertheless wants to verify syntactic correctness of the source, i.e., it catches syntax errors in its input. (I once wrote a source preprocessor for debugging which implemented execution-time line-number/function/module identification which fit this description -- sort of like the PL1 compile-time `statement' condition -- but a really fancy `C beautifier' would fit the bill.) The obvious way to proceed is to snarf the PCC parser, which is written in Yacc, and replace all the action rules which build the parse trees the compiler will eventually need with action code which does what you want. This guarantees that the reductions executed by your preprocessor are exactly the same as by PCC. Clearly there is no need to bother maintaining a symbol table.... Wrong!!! A typedef changes the `syntax' of the language. Consider the following declaration: static foo; /* foo is a static int */ Then consider: typedef float foo; static foo; /* this does absolutely nothing!!! */ In the first fragment the token foo is parsed as an identifier. In the second, foo is parsed as an attribute, and no identifier is declared. Furthermore, the following is unsyntactic in the first program, but normal usage in the second: static foo bar; As near as I have been able to determine, typedef is the *only* construction in C -- other than the preprocessor, which is hardly a part of the language at all -- which can affect parsing nonlocally in this manner. Have a nice context-free day. Steve Haflich MIT Experimental Music Studio