[comp.lang.c++] Enumerated types in C++

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?