richardh@killer.UUCP (11/26/87)
In article <1203@lznv.ATT.COM>, psc@lznv.ATT.COM (Paul S. R. Chisholm) writes: > <PS/2: yesterday's hardware today; OS/2: yesterday's software tomorrow> > > In article <1610047@hpcvlo.HP.COM>, jason@hpcvlo.HP.COM (Jason Su) writes: > > /* Here's another irritating bug that compiled(!) w/o errors on MSC 4.0. */ > > typedef int map; > > > > typedef struct { > > int *map; /* <-- This is the error line */ > > } my_struct; > > K&R, p. 200: "Declarations whose 'storage class' is typedef do not > define storage, but instead DEFINE IDENTIFIERS WHICH CAN BE USED LATER > AS IF THEY WERE TYPE KEYWORDS . . ." [emphasis mine] > > The identifier "map" is effectively a reserved keyword from the time > its typedef is complete through the end of the compiled module. MSC > 4.0 was incorrect in accepting this code in the first place. I suspect > that most C compilers that support typedef will reject it. > The above code fragment compiles without error for a very good reason: there are no errors in it. There are, however, two errors of understanding in the above. 1) The use of a name in a typedef does not create a keyword any more than the declaration of a function or variable does. "As if" doesn't mean "is". The name is still free to be used in any other valid context. 2) There is no name conflict in the above. The first declaration using the name "map" causes the identifier to be placed in the name space associated with variables, functions, typedef names, and enumeration constants. The second causes the identifier "map" to be placed in the name space associated with component names. There is no conflict because the second name will always occur in a context involving selection (xxx.map or xxx->map). Most modern C compilers recognize five distinct overloading classes (also called name spaces): 1) preprocessor macro names; 2) statement labels; 3) structure, union, and enumeration tags; 4) component names; and 5) other names (variables, functions, typedef names, enumeration constants). This can lead to such abominations as: struct horrid { char *horrid_string; struct horrid *horrid; } horrid; Now *horrid.horrid is a struct horrid. Sorry that I can't get a label in there somewhere. Don't take my word for it. Check Harbison and Steele p. 53, sec. 4.2.4 (1st ed.). You folks need to understand C before you start saying a code fragment is right or wrong. richard hargrove ...!killer!richardh -------------------