asc@concurrent.co.uk (Andy Chittenden) (04/14/89)
Enumerated types in C++ are not strictly typed like they are in other languages. A statement of the form: enum { FALSE = (0 != 0), TRUE = (0 == 0) } bool; does not prevent values other than TRUE or FALSE to be assigned to the variable bool. In C++, the above statement is synonymous with: declaring an int called bool declaring two constants called FALSE and TRUE. What this means is that strict type checking is not performed for enumerated types so if we have another enumerated type: enum { RED, BLUE, GREEN } colour; we are still allowed to say: colour = TRUE; Solution ________ The above problem can be circumvented by using two C++ classes for each enumerated type required. For example, class ColourEnumerator { enum { red, blue, green } colour; public: void RED(); void BLUE(); void GREEN(); }; void ColourEnumerator::RED() { colour = red; }; ..... and similarly for BLUE() and GREEN() typedef void (ColourEnumerator::*ColourEnumeratorMemberPtr)(); // it would be nice if this typedef could be // declared within the Colour class (although // Cfront doesn't object, the generated C does // not compile) class Colour { ColourEnumerator colour; public: Colour(); Colour& operator=(const Colour&); Colour& operator=(ColourEnumeratorMemberPtr); // I would like to make this a const // parameter also but C++ won't let me (any // ideas?) }; Colour::Colour() {} Colour& Colour::operator=(const Colour& p_colour) { colour = p_colour.colour; return *this; } Colour& Colour::operator=(ColourEnumeratorMemberPtr& p_setting) { (colour.*p_setting)(); // actually set the colour return *this; } Although the above looks complicated to set up, it enables very strong type checking when actually using a Colour. To set a Colour use: Colour x; x = ColourEnumerator::RED; // turns x RED Rgds, Andy Chittenden Concurrent Computer Corporation 227 Bath Road Slough SL1 4AX England
rfg@riunite.ACA.MCC.COM (Ron Guilmette) (04/16/89)
In article <874@sl10c.concurrent.co.uk> Andy Chittenden <asc@concurrent.co.uk> writes: >Enumerated types in C++ are not strictly typed like they are in other >languages. A statement of the form: > > enum { FALSE = (0 != 0), TRUE = (0 == 0) } bool; > >does not prevent values other than TRUE or FALSE to be assigned to the >variable bool. Since someone else has opened up the topic of enum types and the degree to which they are "strictly typed", I would like to pose another "language lawyer" type question. I have just learned that the following pair of declarations, if given within the same scope, is illegal (at least GNU G++ thinks so): enum color { red, orange, yellow }; enum fruit { banana, pear, orange }; A look at *The Book* tells why. Essentially, the above declarations are considered to be shorthand for: typedef int color; const int red = 0; const int orange = 1; const int yellow = 2; typedef int fruit; const int banana = 0; const int pear = 1; const int orange = 2; // ERROR - redeclared Thus, there is an illegal redeclaration of orange within the same scope. Now consider the following which G++ *does* allow: ----------------------------------------------------------------------------- enum color { red, green, blue }; enum fruit { apple, banana }; overload function; void function (color c) { } void function (fruit f) { } void function (int i) { } int test () { function (apple); function (red); function (99); } ----------------------------------------------------------------------------- For the three function calls the compiler performs a disambiguation process for the overloaded function which takes into account the specific enum type of each constant argument. Yet if we go strictly by the "shorthand" rule, in which enum type declarations are just shorthand for a series of const int declarations, then this disambiguation should never take place, and we should get errors for effectively providing three different definitions for the "void function (int)" function. Is g++ handling the above source code incorrectly, or does a "standard conforming" C++ compiler/translator have to remember the precise (enum) type associated with any given enum constant name? If it does have to remember, then does it also have to get temporary amnesia in most cases? I guess that the bottom line question is "What is the TYPE of an enum constant?" -- // Ron Guilmette - MCC - Experimental Systems Kit Project // 3500 West Balcones Center Drive, Austin, TX 78759 - (512)338-3740 // ARPA: rfg@mcc.com // UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg
diamond@diamond.csl.sony.junet (Norman Diamond) (04/17/89)
In article <176@riunite.ACA.MCC.COM> rfg@riunite.UUCP (Ron Guilmette) writes: i >Now consider the following which G++ *does* allow: n > e >enum color { red, green, blue }; w >enum fruit { apple, banana }; s > >overload function; s >void function (color c) { } u >void function (fruit f) { } c >void function (int i) { } k > s >int test () >{ - > function (apple); - > function (red); - > function (99); - >} - > - >Is g++ handling the above source code incorrectly, or does a "standard conforming" - >C++ compiler/translator have to remember the precise (enum) type associated with - >any given enum constant name? This does seem to be an error in g++. Since C++ usually tries to be compatible with C (and Pantsy C), apple and red must be constants of some integral type, and color and fruit must be some integral type. If color and fruit are int itself, then the three declarations of f cannot be disambiguated, and all three calls are ambiguous. If color and fruit are (say) short and/or unsigned, then the first two declarations of f still cannot be disambiguated, and all three calls are still ambiguous. If function is not overloaded but only declared to take an argument of color, then all three calls must call it. Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.jp@relay.cs.net) The above opinions are my own. | Why are programmers criticized for If they're also your opinions, | re-inventing the wheel, when car you're infringing my copyright. | manufacturers are praised for it?