Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > how to restrict enum conversions ?

Reply
Thread Tools

how to restrict enum conversions ?

 
 
O. Zimmermann
Guest
Posts: n/a
 
      11-15-2005

Hi all,

A variable with an enumerated type can be set with a value from any
other generic "enum" type in the program, or with an integer value,
without notice to the user, neither at compilation nor at execution.

How can I make this IMPOSSIBLE (so that ONLY a value from the expected
enumerated type can be fed to the variable, with no implicit
conversion allowed ?).

Is "typedef enum" the way to go ?


Thanks for your insights - oz
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      11-15-2005


O. Zimmermann wrote On 11/15/05 10:58,:
> Hi all,
>
> A variable with an enumerated type can be set with a value from any
> other generic "enum" type in the program, or with an integer value,
> without notice to the user, neither at compilation nor at execution.
>
> How can I make this IMPOSSIBLE (so that ONLY a value from the expected
> enumerated type can be fed to the variable, with no implicit
> conversion allowed ?).
>
> Is "typedef enum" the way to go ?


No; an `enum xxx' type is just an ordinary integer
of a compiler-determined flavor, and the enumerated
names themselves are merely `int' constants.

Here's a hack inspired by Java that would solve
part of your problem:

typedef struct {
int value;
} Veggie;

const Veggie AVOCADO = { 1 };
const Veggie BANANA = { 2 };
...
const Veggie ZUCCHINI = { 26 };

typedef struct {
int value;
} Animal;

const Animal AARDVARK = { 1 };
const Animal BEAR = { 2 };
...
const Animal ZEBRA = { 26 };

This will allow `Veggie v1 = AVOCADO', for example,
but `Veggie v2 = AARDVARK' will provoke a compile-time
diagnostic.

It's not perfect, though. You can't prevent someone
from writing `Veggie v3 = { -42 }', for example. Also,
you give up the ability to use AVOCADO et al. as case
labels, or to compare `v3 == ZUCCHINI'. It's up to you
to decide whether the drawbacks of the scheme are more
or less painful than trying to police the use of enums.

--
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      11-15-2005
"O. Zimmermann" <(E-Mail Removed)2p3.fr> writes:
> A variable with an enumerated type can be set with a value from any
> other generic "enum" type in the program, or with an integer value,
> without notice to the user, neither at compilation nor at execution.
>
> How can I make this IMPOSSIBLE (so that ONLY a value from the expected
> enumerated type can be fed to the variable, with no implicit
> conversion allowed ?).
>
> Is "typedef enum" the way to go ?


Basically, you can't (other than by using a different language).
Enumeration types are really nothing more than thinly veiled integers.
Typedef won't help; it just creates an alias for an existing type, not
a new type.

There are ways to do similar things (Eric Sosman posted some ideas),
but they have drawbacks.

C generally has weak type checking -- or, more precisely, it provides
implicit conversions in a lot of cases. As Eric points out, there are
no such implicit conversions for struct types.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
August Karlstrom
Guest
Posts: n/a
 
      11-15-2005
O. Zimmermann wrote:
> A variable with an enumerated type can be set with a value from any
> other generic "enum" type in the program, or with an integer value,
> without notice to the user, neither at compilation nor at execution.
>
> How can I make this IMPOSSIBLE (so that ONLY a value from the expected
> enumerated type can be fed to the variable, with no implicit conversion
> allowed ?).


I don't think you can. Switch to a language which focus on safety.


August

--
I am the "ILOVEGNU" signature virus. Just copy me to your
signature. This email was infected under the terms of the GNU
General Public License.
 
Reply With Quote
 
plunket@gmail.com
Guest
Posts: n/a
 
      11-15-2005
> How can I make this IMPOSSIBLE (so that ONLY a value from the expected
> enumerated type can be fed to the variable, with no implicit
> conversion allowed ?).


"Impossible" is a strong word.

However, if you want to "play nice" and restrict yourself to an API
(which has hopefully-obvious paths for release-build optimizations if
desired), do something like I demonstrate below. This can become
considerably easier if you don't allow "holes" in the values you
operate on, and easier yet again if you always start at zero (e.g.
don't provide MY_ENUM_VAL).

The way this is split between headers and implementation files is left
to the reader. The key here is that the list of enum names is only
defined in one list. Duplication being the root of all evil and all
that...

I have used a system much like this for file reading and writing, where
the code that read and wrote enums used the symbolic version of the
enum value, so config files would be more readily readable by the end
user.

#define MY_ENUM_LIST \
MY_ENUM(Apple) \
MY_ENUM(Banana) \
MY_ENUM_VAL(Avocado, 26)

#define MY_ENUM(x) x,
#define MY_ENUM_VAL(x, y) x = y,

typedef enum _Fruit
{
MY_ENUM_LIST
} Fruit;

#undef MY_ENUM
#undef MY_ENUM_VAL

#define MY_ENUM(x) x,
#define MY_ENUM_VAL(x, y) x,

Fruit g_allowedFruit[] = { MY_ENUM_LIST };
int g_numAllowedFruits = sizeof(g_allowedFruit) /
sizeof(g_allowedFruit[0]);

#undef MY_ENUM
#undef MY_ENUM_VAL

int FindFruit(Fruit f)
{
/* Binary search the allowed list, and return the correct index.
Return -1 on error */
}

Fruit NextEnum(Fruit f)
{
int index = FindFruit(f)
index++;
if (index < g_numAllowedFruits)
return g_allowedFruit[index];
else
ItsAnError();
}

Fruit PreviousEnum(Fruit f)
{
int index = FindFruit(f)
index--;
if (index >= 0)
return g_allowedFruit[index];
else
ItsAnError();
}

int ValidateEnum(Fruit f)
{
return (FindFruit(f) >= 0);
}

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
enum: display elements of an enum specified at runtime Jerminia Java 3 10-07-2005 10:08 PM
Pointer conversions and Data types conversions vb@gmail.com C Programming 10 08-05-2005 09:51 AM
enum within an enum - Java 6 06-13-2005 12:51 AM
How to enum an enum? Ernst Murnleitner C++ 5 11-13-2003 11:06 AM



Advertisments