    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: All You Need to Know About enums</title>
        <link>https://members.accu.org/index.php/articles/861</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 11, #3 - Apr 1999</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c132/">113</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-132/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+132/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;All You Need to Know About enums</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 April 1999 13:15:30 +01:00 or Sat, 03 April 1999 13:15:30 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>I am preparing the appendices for a book that I am writing and
thought that reading them might be beneficial to some members and
that others might be able to provide constructive criticism.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e24" id="d0e24"></a>The C Version
of enum</h2>
</div>
<p>C for reasons best known to its designers has a special
namespace - tag space - for the tags that come between the keywords
that introduce a user defined type and the opening brace of the
definition. This means that you have to use typedef to create a
typename for an <tt class="literal">enum</tt> (as well as for
<tt class="literal">struct</tt> and <tt class="literal">union</tt>
types).</p>
<p>The second feature of C is that an <tt class="literal">enum</tt>
will have an underlying integer type (implementation defined) to
provide its values and that all the 'legal' values of the
underlying type will also be 'legal' values for the <tt class=
"literal">enum</tt> type. There is a requirement that effectively
constrains the underlying type to be an <tt class="type">int</tt>
or convertible to an <tt class="type">int</tt> without loss of
data.</p>
<p>The enumeration constants of an <tt class="literal">enum</tt>
are compile time constants. The values are either declared by
explicit initialisation, or implicitly as 1 more than the preceding
item in the enumeration list. If not given an explicit value the
first enumerated constant in the enumeration list is zero.</p>
<p>Here are some examples to help clarify the text:</p>
<pre class="programlisting">
enum Wheels { bicycle = 2, motorcycle = 2, tricycle = 3, car = 4};
enum Index { zero, one, two, three, four};
enum Colour {red=1, green, blue=4};
</pre>
<p>'<tt class="literal">Wheels</tt>', '<tt class=
"literal">Index</tt>' and '<tt class="literal">Colour</tt>' are not
type names in C, they are just tag names so they must be prefixed
with enum wherever they are used. However tag names do not conflict
with other non-tag uses of the same 'name' in the same scope. So we
can write:</p>
<pre class="programlisting">
typedef enum Wheels Wheels;
</pre>
<p>which means that the second use of '<tt class=
"literal">Wheels</tt>' in that declaration is an ordinary typename
for the type identified by <tt class="literal">enum</tt> <tt class=
"type">Wheels</tt>. C programmers will insist on writing things
like that with the result that novices get totally confused.</p>
<p>That is about it. In other words <tt class="literal">enum</tt>s
in C are very weak user defined types. None the less they can be
very useful. For example they are, in my opinion, a better option
for providing compile time integer constants than the more
traditional method via the preprocessor. In my opinion #define
should only be used to provide integer constants for use by the
preprocessor. So I have no problem with:</p>
<pre class="programlisting">
#define MSDOS 1
#if MSDOS
#include &lt;dos.h&gt;
#endif
</pre>
<p>But I have serious reservations over:</p>
<pre class="programlisting">
#define MAXSIZE 100
char buffer[MAXSIZE];
</pre>
<p>and would prefer:</p>
<pre class="programlisting">
struct ProgramLimits{ mazsize = 100};
char buffer[maxsize];
</pre>
<p>However I suspect that the traditionalists will argue strongly
for the preprocessor solution.</p>
<p>Another place where enums are useful in C are for the control
values for a switch statement. For example consider a menu where
the selection is controlled by a switch. Which of the following is
easier to maintain:</p>
<pre class="programlisting">
switch(tolower(getc(stdin))){
  case 'R' : getdata(); break;
  case 'W' : writedata(); break;
  case 'Q' : exit(); 
}
</pre>
<p>or</p>
<pre class="programlisting">
enum {read_in = 'r', write_out='w', quit = 'q'};
switch(tolower(getc(stdin))){
  case read_in : getdata(); break;
  case write_out : writedata(); break;
  case quit : exit(); 
}
</pre>
<p>Not convinced? Well which will be easier to convert to handle a
menu that is being displayed in French though it has the same
functionality? The traditional way of using a switch to select on
the basis of a response to a menu is highly dependant on the
natural language being used to display messages. We cannot remove
this dependence but we can try to localise it.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e112" id="d0e112"></a>C++ and
enum</h2>
</div>
<p>If I understand the C rules correctly, C provides an implicit
conversion between enum values and ints in both directions. In
other words C has no great problem with:</p>
<pre class="programlisting">
enum X { zero, one two };
enum X x=0;
</pre>
<p>In general C++ tries to ensure that code that is valid C will
remain valid C++, however sometimes this seems to be unreasonable
(perhaps because C is taking, in the eyes of the designers of C++,
one liberty too many). In the case of <tt class=
"literal">enum</tt>s the designers of C++ considered the implicit
cast from <tt class="type">int</tt> to a <tt class=
"literal">enum</tt> type to be one of these cases. In C++ there is
no implicit conversion from any other type to any specific
<tt class="literal">enum</tt> type. That means that you can only
assign a value of the correct enumerated type to an <tt class=
"literal">enum</tt> variable. If you want to do something else you
must use a cast.</p>
<p>In addition, there are no built-in arithmetic operators for
enumerated types, though programmers can provide their own. (Note
however, that you cannot provide an assignment for an enum, the
built-in bitwise copy is all you have). So we have:</p>
<pre class="programlisting">
enum Colour {Black, Red, Green, Blue=4, White=7};
int main(){
  Colour c0=Black, c1=Green, c2;
  c2 = c0 + c1;  // error no conversion from int to Colour
  c2 = Colour(c0+c1);
}
</pre>
<p>Note the further difference between C and C++. C++ has no tag
space (<span class="emphasis"><em>actually for backward
compatibility it allows an awful hack, if the same name is used for
a typename and an identifier name enum (struct, union or class) can
be used to disambiguate. Never willingly do this but you may have
to use it when calling third party code.</em></span>) What were
tags in C have grown up to become full typenames in C++ so we
neither need a typedef nor an enum prefix to use Colour as a full
user defined type.</p>
<p>The next feature is that when you do arithmetic on <tt class=
"literal">enum</tt>s the default behaviour is to convert them to
<tt class="type">int</tt>s. So in the above code <tt class=
"literal">c0 + c1</tt> is computed with <tt class="type">int</tt>
arithmetic and so evaluates to an <tt class="type">int</tt>.
Because there is no implicit conversion available, you then have to
explicitly create a <tt class="type">Colour</tt> value from the
<tt class="type">int</tt> value. In theory you could provide
overloaded arithmetic operators, but the lack of an implicit
conversion means that we would have to provide three versions of
each to cover all the bases:</p>
<pre class="programlisting">
Colour operator + (Colour, Colour);
Colour operator + (int, Colour);
Colour operator + (Colour, int);
</pre>
<p>I doubt that many would think this worth the effort. Generally
we do not use <tt class="literal">enum</tt>s for arithmetic. See
the text box for more detail on this.</p>
<p>Another difference between C and C++ <tt class=
"literal">enum</tt>s is in the range of values that must be
supported. In C all values of the underlying type (if only you knew
what that was - read the compiler documentation for the answer).
C++ is much more restrictive. You must determine the number of bits
that are required to represent (in binary) the enumerated constants
(I am still unclear if an implementor is permitted to use some
scheme of base+offset, I think not but I may be wrong). This opens
up the potential for packing enums in an array. In practice I have
never come across a compiler that does anything different in C++
from what you get in C. However, strictly speaking in the context
of:</p>
<pre class="programlisting">
typedef enum Colour{Black, Red, Green, Blue=4, White=7} Colour;
</pre>
<p>The following is valid in C but undefined in C++:</p>
<pre class="programlisting">
Colour c = 255;
</pre>
<p>Because 127 requires 7 bits while White only requires 3. But the
smallest underlying type is char and that must be able to represent
127.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e188" id="d0e188"></a>Summary</h2>
</div>
<p>There are differences between C and C++ language specifications
of enum. However with the exception of the naming rules (tags
versus typenames) and the rule about implicit conversion from
<tt class="type">int</tt> to an <tt class="literal">enum</tt> you
are unlikely to ever need to know them in practice (though they
make silly test questions and good quiz questions for language
lawyers.)</p>
<p>While enums can be used to provide extra integer types
(superficially useful in C++ where they can be used for
overloading) actually using them for arithmetic is probably
unwise.</p>
<p><tt class="literal">enum</tt>s are a good mechanism for
providing portable (between C and C++) compile time constants and
are certainly superior to the older mechanism via the preprocessor.
However in the scope of a class or namespace const qualified values
are probably better style (no use for portability between C and C++
though because const values are not compile time constants in
C)</p>
<p>Finally in C++ <tt class="literal">enum</tt>s are an excellent
tool for knocking off quick, simple exception types. If you do not
want any associated information they can even be empty:</p>
<pre class="programlisting">
enum MyException {};
</pre>
<p>Now what have I left out?</p>
<div class="sidebar">
<p class="title c2">Extra Arithmetic Types in C++</p>
<p>If you want a full-fledged arithmetic type there is another way
of achieving such in C++:</p>
<pre class="programlisting">
class myInt {
  myInt(int v = 0): value(v) {}
  operator int (){return value;}
private:
  int value;
};
</pre>
<p>I think this is a better way of providing a distinct arithmetic
type that behaves very like a built-in one. Furthermore the idea
extends to float types as well. If you want named values you can
provide them via either class static <tt class=
"literal">const</tt>s or as namespace <tt class=
"literal">const</tt>s (I prefer the later because of the using
declarations that will allow you to avoid constant repetition of
the scope qualifier.) So we might have:</p>
<pre class="programlisting">
namespace mathematicalConstants{
  class myDouble {
    myDouble(double v = 0): value(v) {}
    operator double(){return value;}
  private:
  double value;
myDouble const pi=3.14159265;
};
int main(){
  using mathematicalConstants::pi;
...
}
</pre>
<p>You might ask what value there is to creating a class like
<tt class="classname">myDouble</tt> when it seems to behave exactly
like a <tt class="type">double</tt>. Well here are a couple of
reasons.</p>
<p>First you can use this class as a base class. You can, but I
would be interested in a good example of why you might want to.
Second you can constrain the behaviour of the type by suppressing
various operators (declaring them <tt class="literal">private</tt>
and not implementing them).</p>
<p>Lastly, though <tt class="classname">myDouble</tt> values freely
convert to and from <tt class="type">double</tt> they cannot
implicitly convert to other user-defined types because of the
restriction on only one user-defined conversion in any implicit
conversion chain. So in the context of the above, give or take a
using declaration:</p>
<pre class="programlisting">
myInt value = pi;
</pre>
<p>Results in an error. I have no idea how useful that is as an
idea and would welcome feedback.</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
