bergsten@chalmers.UUCP (Per Bergsten) (08/03/87)
(Maybe this message should go to comp.bugs.something or sunspots). The recent discussion about relative merits of the "enum" type made me remember an obscure bug in PCC I discovered some time ago and (almost) forgot. The following example should NOT be construed as a discredit to the idea of enum. I am prepared to accept all the help the language/compiler can give; I regard "enum" types as a small but not useless tool. However, current implementations are lacking in quality. ------------------------------------------------------------------------------- Consider: typedef enum { a=0, b=1, c=2 } t1; mine() { printf("mine: a=%d, b=%d, c=%d\n", a, b, c); } main() { typedef enum { b=0, c=1, d=2 } t2; mine(); printf("main: b=%d, c=%d, d=%d\n", b, c, d); exit(0); } On VAX/BSD 4.2 and on SUN-3/SunOs3.2 I obtain the following output: mine: a=0, b=1, c=2 main: b=1, c=2, d=2 ^ ^ In my opinion this is wrong. I do confess I don't have access to a C-standard document so my understanding of C is largely based on K&R and some 8 years of practise, nevertheless I don't think that the compiler behaves correctly. At the very least I would expect an error message if this is an illegal program. Incidentally: lint (in verbose mode) only prints a warning that "b" and "c" are redefined. ------------------------------------------------------------------------------- Per Bergsten bergsten@chalmers.se ........!mcvax!enea!chalmers!bergsten a.k.a perb%holtec.uucp@chalmers
ron@topaz.rutgers.edu (Ron Natalie) (08/04/87)
I'm surprised this works at all. YOU NEVER DECLARE ANY VARIABLES
decot@hpisod2.HP.COM (Dave Decot) (08/05/87)
> I'm surprised this works at all. YOU NEVER DECLARE ANY VARIABLES
While the example does not declare any variables, it also does not
refer to any. a, b, and c are constants.
Dave Decot
hpda!decked
mnc@m10ux.UUCP (Michael Condict) (08/07/87)
In <13700@topaz.rutgers.edu>, ron@topaz.rutgers.edu.UUCP writes: > I'm surprised this works at all. YOU NEVER DECLARE ANY VARIABLES Why do you think he should need to declare any variables in order to obtain enum constants that can be passed to the printf function? The confusion displayed by this and previous postings on the subject of enums in C has been dealt with here before, by a posting from Dennis Ritchie, among others. To summarize: PCC-BASED COMPILERS (System V, BSD, Sun, ...) DO NOT CORRECTLY IMPLEMENT ENUMS. In fact, they do not even provide an implementation that is useable without excruciating effort on the part of the user. Here is the correct definition, as intended by Ritchie and as described in the System V C Reference Manual (any mistakes are mine): The occurrence of: enum [ tag ] { e_1 [ = val1 ] , ... , e_n [ = val_n ] } (whether or not it is inside a typedef, has an enum tag, or is fol- lowed by declarators declaring variables) should have the effect of introducing n new names, e_1 through e_n, that are of integral type and can be used anywhere an integral const is allowed. These new names have the same scope (are in the same symbol table) as if they had been introduced by: int e_1, ..., e_n; immediately following the declaration that contains the enum construct. This implies that the program in the referenced article, which had roughly the following: typedef enum { a=0, b=1, c=2 } t1; void main() { typedef enum { b=0, c=1, d=2 } t2; ... is correct, and the compiler is wrong. The scope of the first b and c enum values overlaps with (surrounds) the scope of the second b and c, but they are different scopes and hence it is legal to redeclare b and c inside the function, just as it would be legal to do the analogous thing with int variables named b and c. The compiler is apparently using one global symbol table for all enum values, which is severely brain damaged. The other bug in pcc, which renders its enums almost unuseable, is that its enums are not type-compatible with ints! This means that you must cast them to (int) to use them as an array subscript or to assign them to an int variable. Strong typing of enums would be nice as an option, but it is only reasonable if it does not prevent you from using enums in type-correct ways in all the contexts that make sense, e.g., as array subscripts. Since there is no way to declare that an array has a particular enum type as its index range, it is unreasonable to have strongly typed enums. NOTE FOR LANGUAGE LAWYERS: In the definition I gave above, there appears to be a glitch. What if the "enum { ... }" occurs in a field declaration of a struct or union? In this case, the obvious desired action is that the scope of the enum constants be the same as the scope of the surrounding struct/union type. Otherwise the field containing the enum construct would be of an enum type whose values are not directly visible, clearly undesirable. Well in fact, strict reading of my words above leads to the desired semantics, because I said "the declaration containing the ...". The word "declaration" has a precise meaning in the published syntax rules for C, and is distinct from "struct-declaration". The former refers only to a top-level declaration, while the latter refers to the declaration of a field within a struct. So the following: struct { int x; enum {a, b} y; } s; should introduce enum consts a and b whose scope is the same as s, not x. -- Michael Condict {ihnp4|vax135|cuae2}!m10ux!mnc AT&T Bell Labs (201)582-5911 MH 3B-416 Murray Hill, NJ