cavrak@uvm-gen.UUCP (Steve Cavrak) (04/29/88)
Can someone explain why the following uses (abuses?) of typdef and enum create problems in the struct that follows them? (The example is taked from a once working program that was being ported to a new compiler that is "now ANSI" compliant. The code has been "tested" on VAX BSD 4.3, VAX VMS, and Turbo-C. The "new" compiler is Waterloo C 3.0.) The available C documentation is not enlightening. I'm sure that my Pascal mindset adds to the confusion. /* Imnotok.c */ /* Confusion using enumerated types in structures */ /* */ /* The "_ok" declaration is usable in the struct definition AND */ /* the "_to" declaration is usable, BUT */ /* the "_no" declaration generates a syntax error. */ /* */ /* Why? */ /* ------------------------------------------------------------------ */ typedef int s_state_ok; /* OK */ typedef enum s_state_ok { initial_ok, middle_ok, final_ok }; typedef int s_state_to; /* OK */ enum s_state_to { initial_to, middle_to, final_to }; typedef enum s_state_no { /* NOT OK */ initial_no, middle_no, final_no }; struct { int m; int n; s_state_ok s; /* s_state_ok works, s_state_no fails */ } machine_state; main () { } ---------------------------------------------------------------- _______ || | Stephen J. Cavrak, Jr. BITNET: sjc@uvmvm |* | CSNET : cavrak@uvm | / Academic Computing Services USENET: cavrak@uvm-gen | | University of Vermont | | Burlington, Vermont 05405 ----
limes@sun.uucp (Greg Limes) (04/30/88)
In article <823@uvm-gen.UUCP> cavrak@uvm-gen.UUCP (Steve Cavrak) writes: >/* The "_ok" declaration is usable in the struct definition AND */ >/* the "_to" declaration is usable, BUT */ >/* the "_no" declaration generates a syntax error. */ >typedef int s_state_ok; /* OK */ >typedef enum s_state_ok { > initial_ok, middle_ok, final_ok > }; > >typedef int s_state_to; /* OK */ >enum s_state_to { > initial_to, middle_to, final_to > }; > >typedef enum s_state_no { /* NOT OK */ > initial_no, middle_no, final_no > }; > >struct { > int m; > int n; > s_state_ok s; /* s_state_ok works, s_state_no fails */ > } machine_state; Small change. The identifier between "enum" and "{" is only an enumerator tag, not a type definition; since enumeration tags and type definitions can never occur in the same place, the compiler can keep separate lists and search only the proper list. note that the only difference between "s_state_ok" and "s_state_no" is whether they appear as the target of a "typedef" statement. To make it all a bit more standard, you might consider making the types analogous to the enumeration tags, as follows: typedef enum s_state_ok { initial_ok, middle_ok, final_ok } s_state_ok; typedef enum s_state_to { initial_to, middle_to, final_to } s_state_to; typedef enum s_state_no { initial_no, middle_no, final_no } s_state_no; struct { int m; int n; s_state_no s; } machine_state; Strictly speaking, the enumeration tags are not needed, unless you want to later use them like enum s_state_no foo; which could in fact now be written as s_state_no foo; Hope this clears things up a bit. -- Greg Limes [limes@sun.com] frames to /dev/fb
wes@obie.UUCP (Barnacle Wes) (05/02/88)
In article <823@uvm-gen.UUCP>, cavrak@uvm-gen.UUCP (Steve Cavrak) writes: | Can someone explain why the following uses (abuses?) of typdef and enum | |a) typedef int s_state_ok; /* OK */ |b) typedef enum s_state_ok { | initial_ok, middle_ok, final_ok | }; | |c) typedef int s_state_to; /* OK */ |d) enum s_state_to { | initial_to, middle_to, final_to | }; | |e) typedef enum s_state_no { /* NOT OK */ | initial_no, middle_no, final_no | }; Your problem lies mainly with your typedef and enum syntax. Remember that the name following the keyword `enum' is an _enumeration type tag_ (like a structure tag), not a variable declaration. The syntax for typedef is to write the keyword typedef, followed by a valid C variable declaration. The name that would normally become the variable becomes the new type name. The enum statement looks like: enum enum_type_tag { element, [elements...] } variable; The typedef statement looks like: type valid_c_variable_declaration; where the variable becomes the new type name. What your code above is actually doing is declaring: a) a new type, s_state_ok, which is int. b) a new enumeration type, which is called s_state_ok (but no variables of this type are declared). c) a new type, s_state_to, which is int. d) a new enumeration type, which is called s_state_to (again no variables of this type are declared). e) a non-working typedef - no variable was included in the 'enum...' statement, so no type name could be found. I think what you may want is: typedef enum { initial_ok, middle_ok, final_ok } s_state_ok ; typedef enum { initial_to, middle_to, final_to } s_state_to ; typedef enum { initial_no, middle_no, final_no } s_state_no ; -- /\ - "Against Stupidity, - {backbones}! /\/\ . /\ - The Gods Themselves - utah-cs!uplherc! / \/ \/\/ \ - Contend in Vain." - sp7040!obie! / U i n T e c h \ - Schiller - wes
throopw@xyzzy.UUCP (Wayne A. Throop) (05/02/88)
> cavrak@uvm-gen.UUCP (Steve Cavrak) > Can someone explain why the following uses (abuses?) of typdef and enum > create problems [...] > typedef int s_state_ok; > typedef enum s_state_ok { > initial_ok, middle_ok, final_ok > }; Saying typedef enum foo {a, b, c}; is about like saying typedef int; or typedef struct foo {int a;int b;int c}; In none of these three cases has a new type name been introduced. Presumably what was meant was typedef enum { initial_ok, middle_ok, final_ok } s_state_ok; The first line where s_state_ok is typedef'ed to be an (int) is not necessary (or legal, or wanted) once it has correctly been coined as an enum type. -- You can lead a yak to water but you can't teach an old dog to make a silk purse out of a pig in a poke. --- Opus -- Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw