bliss@sp64.csrd.uiuc.edu (Brian Bliss) (01/31/91)
The alliant fx C compiler (for an fx1 or fx8, not fx2800), supports them, but gives errors when you try to compare two enum constants. bb
steve@taumet.com (Stephen Clamage) (02/01/91)
bliss@sp64.csrd.uiuc.edu (Brian Bliss) writes: > The alliant fx C compiler (for an fx1 or fx8, not fx2800), supports > them, but gives errors when you try to compare two enum constants. Enums are well-defined and safe in standard (ANSI/ISO) C. However, enums were introduced helter-skelter by different vendors years earlier, with no written standard to refer to. Apart from compiler bugs, different implementors had different ideas of how enums should work. At least one vendor did not allow an enum to index an array, for example. So if you need to port code among lots of pre-standard or non-standard compilers, it is probably best not to use enums. -- Steve Clamage, TauMetric Corp, steve@taumet.com
dave@cs.arizona.edu (Dave P. Schaumann) (02/01/91)
bliss@sp64.csrd.uiuc.edu (Brian Bliss) writes: BB> The alliant fx C compiler (for an fx1 or fx8, not fx2800), supports BB> them, but gives errors when you try to compare two enum constants. steve@taumet.com (Stephen Clamage) writes: SC>Enums are well-defined and safe in standard (ANSI/ISO) C. However, SC>[there are pre-ANSI compilers out there that get them wrong]. SC>So if you need to port code among lots of pre-standard SC>or non-standard compilers, it is probably best not to use enums. (sarcasm 'on) Of course, if you want to port to a machine that doesn't have a C compiler at all, you'd better not even use C. Maybe you'll want to port to a machine that doesn't have a compiler that allows floating point numbers. Better not use those, either. Let us all now observe a moment of silence for the god Portability. (sarcasm 'off) (soapbox 'on) Portability is a slippery issue. People like to treat it like absolute portability is a reasonable and possible goal. But it is not possible to write a program that is absolutely portable to every platform on God's Green Earth. (By absolutely portable, I mean compilable/interpretable with *no* modifications whatsoever). Absolute portability is a grail no-one can reach. Realistic portability is balancing a trade-off. The wider the range of computers you wish to port to, the fewer language choices you have, and the fewer language features you can count on to be there and work right. Even if you restrict yourself to platforms that have some kind of C compiler, you are still faced with a wildly varying field of language features and qualities of implementation. To have even realistic portability, you have to expect at least a little editing on the target machine (in the general case). (soapbox 'off) If you're porting a program that uses enums to a compiler that doesn't have enums, or has broken enums, it is a fairly simple proceedure (in fact, it can be automated) to use #defines as a work-around. Dave Schaumann | And then -- what then? Then, future... dave@cs.arizona.edu | -Weather Report
enag@ifi.uio.no (Erik Naggum) (02/01/91)
In article <1991Jan30.210255.16804@csrd.uiuc.edu>, Brian Bliss writes:
The alliant fx C compiler (for an fx1 or fx8, not fx2800), supports
them, but gives errors when you try to compare two enum constants.
bb
Assume these definitions:
enum { frotz, klutz } foo; [1]
enum { gunk, junk } bar; [2]
Which of these are your compiler complaining against?
frotz == klutz [3]
frotz == gunk [4]
frotz < klutz [5]
frotz < junk [6]
The declaration in [1] declares a distinct (anonymous) type of which
foo is an object. Likewise [2] declares another distinct (anonymous)
type of which bare is an object. frotz and klutz [1] are names of
constant values of the type of object of which foo is an instance.
Likewise for gunk and junk [2].
This makes the comparison in [3] valid (but slightly pointless), since
we're comparing values of the same type, while the latter does not.
In [5] and [6], "<" could be any of "<", "<=", ">", and ">=". I'm not
sure about the welldefinedness of these comparisons, since I have seen
compilers barf on expressions such as
foo < klutz [7]
since it implicitly entails a conversion to int, which nonetheless is
the base type for enums. Careful consulting of the ANSI C standard
may be needed to verify this.
It would be helpful if you gave examples of the code on which your
compilers gags, as well as the precise error message produced.
--
[Erik Naggum] Snail: Naggum Software / BOX 1570 VIKA / 0118 OSLO / NORWAY
Mail: <erik@naggum.uu.no>, <enag@ifi.uio.no>
My opinions. Wail: +47-2-836-863 Another int'l standards dude.
sarima@tdatirv.UUCP (Stanley Friesen) (02/05/91)
In article <ENAG.91Feb1003707@hild.ifi.uio.no> enag@ifi.uio.no (Erik Naggum) writes: >Assume these definitions: > enum { frotz, klutz } foo; [1] > enum { gunk, junk } bar; [2] > ... >The declaration in [1] declares a distinct (anonymous) type of which >foo is an object. Likewise [2] declares another distinct (anonymous) >type of which bare is an object. So far so good. ANSI does indeed specify that each enumeration is a distinct type. > frotz and klutz [1] are names of >constant values of the type of object of which foo is an instance. >Likewise for gunk and junk [2]. However here you deviate from the ANSI standard. According to 3.5.2.2 (Semantics): "The identifiers in an enumerator list are declared as constants that have type int and may appear anywhere such are permitted". Thus frotz, klutz, gunk, and junk are all *int's*, and may be used anywhere an int may be used. This includes *all* forms of comparison, thus: (klutz == gunk) is a perfectly valid ANSI C construct, and evaluates to true if and only if the value of klutz equals the value of gunk. (This is also a constant expression, that can be evaluated wholly by the compiler) Any C compiler that fails to accept this is *not* ANSI C. (It may be a valid pre-ANSI compiler though). -- --------------- uunet!tdatirv!sarima (Stanley Friesen)
torek@elf.ee.lbl.gov (Chris Torek) (02/14/91)
In article <128@tdatirv.UUCP> sarima@tdatirv.UUCP (Stanley Friesen) writes: >According to 3.5.2.2 (Semantics): >"The identifiers in an enumerator list are declared as constants that >have type int and may appear anywhere such are permitted". Note, however, that a good compiler can (and probably should) emit a warning when enumeration constants for different enumerated types are compared. That is, given enum { apple, pear, orange } fruits; enum { lima, green, black } beans; a good compiler would complain differently about the comparision: if (apple == orange) than about the comparison: if (lima == pear) Both of these are effectively the same as `if (0)', hence a good compiler should warn about a constant in conditional context as well as mixing enumeration types (in the second example) and code that is not reached (assuming there are no labels following the comparisons). All of these are legal ANSI C expressions (despite the comparison of apples and oranges). Incidentally, one apple is worth a lot of Lima beans. :-) -- In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427) Berkeley, CA Domain: torek@ee.lbl.gov