Topic: is iterating over an enum conformant?


Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Wed, 29 Jun 2005 09:54:39 CST
Raw View

Gianluca wrote:
> Hi,
> A doubt slipped into my mind. I wonder if this piece of code is ok from
> the standard point of view (the idea comes from real life, but the
> example is totally artificial):
>
> enum eEnum { eE1 = 0, eE2, eE3, eTotal };
>
> int anArray[eTotal] = {};
>
> int main()
> {
>   for (int i(eE1); i < eTotal; ++i)
>   {
>      anArray[i] = i;
>   }
> }

That code is perfectly valid, but it uses a lot of implicit conversion
to ints. You could always define an operator++ for your enum -

inline eEnum &operator++(eEnum &a) throw() { a = eEnum(a + 1); return a
};

You can therefore code your loop as

for (eEnum i = eE1; i < eTotal; ++i) { anArray[i] = i; }

You can also choose to put checking inside the operator++ code if you
do that to stop people going out of range.

It is a little more type-safe.

Tp,

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.fr
Date: 24 Jun 2005 14:10:24 GMT
Raw View
Gianluca wrote:

> A doubt slipped into my mind. I wonder if this piece of code
> is ok from the standard point of view (the idea comes from
> real life, but the example is totally artificial):

> enum eEnum { eE1 = 0, eE2, eE3, eTotal };

> int anArray[eTotal] = {};

> int main()
> {
>   for (int i(eE1); i < eTotal; ++i)
>   {
>      anArray[i] = i;
>   }
> }

Totally standards compliant, but a bit fragile.  Anytime you're
doing something like this, you should at least put a comment
next to the enum definition, so that a maintenance programmer
knows 1) to leave eTotal as the last entry, and 2) not to add
any = constant clauses to the enum.  (For that matter, your = 0
is unnecessary as well.)

FWIW: I often go one further, with something like:

    Data array[] =
    {
        dataForE1,
        dataForE2,
        dataForE3
    } ;

It's definitly something that needs watching out for during
maintenance, but the alternatives are all so much more
expensive...

--
James Kanze                                           GABI Software
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Gianluca" <dishsi@tin.it>
Date: Thu, 23 Jun 2005 10:28:02 CST
Raw View
Hi,
A doubt slipped into my mind. I wonder if this piece of code is ok from
the standard point of view (the idea comes from real life, but the
example is totally artificial):

enum eEnum { eE1 = 0, eE2, eE3, eTotal };

int anArray[eTotal] = {};

int main()
{
  for (int i(eE1); i < eTotal; ++i)
  {
     anArray[i] = i;
  }
}

Thanks,
Gianluca

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Me" <anti_spam_email2003@yahoo.com>
Date: Fri, 24 Jun 2005 08:59:03 CST
Raw View
> A doubt slipped into my mind. I wonder if this piece of code is ok from
> the standard point of view (the idea comes from real life, but the
> example is totally artificial):

Yes.

> enum eEnum { eE1 = 0, eE2, eE3, eTotal };
>
> int anArray[eTotal] = {};

Yes. eTotal is an integral constant expression so it is accepted when
specifying the bounds.

> int main()
> {
>   for (int i(eE1); i < eTotal; ++i)

Yes. eE1 is implicitly converted to an int during integral promotions.
i < eTotal converts eTotal to int in this case and does the comparison
on two ints.

>   {
>      anArray[i] = i;
>   }
> }

The code above is correct. Two things you have to watch out for the
above code is that eE1 to eTotal has to be consecutive integers that
fit into an integer of type int. For example, you can have the case
where:

INT_MAX == 0x7FFF
UINT_MAX == 0xFFFF

enum eEnum {eE1 = 0x7FFF, eE2, eTotal};

It is unspecified what the underlying type of eEnum is but one thing
that is clear is that it has to be larger than an int. So your above
code would break. Unfortunately there is no way to get the exact
underlying type of an enum but you can get a conservative approximate
of it like this:

template<int> struct underlying_enum;

template<> struct underlying_enum<1> { typedef int type; };
template<> struct underlying_enum<2> { typedef unsigned int type; };
template<> struct underlying_enum<3> { typedef long type; };
template<> struct underlying_enum<4> { typedef unsigned long type; };

template<class T> void underlying_helper(T);
char (&underlying_helper(int))[1];
char (&underlying_helper(unsigned int))[2];
char (&underlying_helper(long))[3];
char (&underlying_helper(unsigned long))[4];

#define underlying_enum(e) \
underlying_enum<sizeof(underlying_helper(+e()))>::type

underlying_enum(eEnum) i = eE1;

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: brangdon@cix.co.uk (Dave Harris)
Date: Fri, 24 Jun 2005 14:00:36 GMT
Raw View
dishsi@tin.it (Gianluca) wrote (abridged):
> A doubt slipped into my mind. I wonder if this piece of code is ok from
> the standard point of view (the idea comes from real life, but the
> example is totally artificial):
>
> enum eEnum { eE1 = 0, eE2, eE3, eTotal };
>
> int anArray[eTotal] = {};
>
> int main()
> {
>   for (int i(eE1); i < eTotal; ++i)
>   {
>      anArray[i] = i;
>   }
> }

It's fine, as long as the int is big enough to hold all the values of the
enum. What made you doubt it would be OK?

-- Dave Harris, Nottingham, UK.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]