assignment of integer to enumerated value

J

John Goche

Hello,

The following program compiler and runs fine under gcc and produces
the output 3. However, I am not sure whether such behavior is legal.
In particular, as a related question, how would I go about checking
that a supplied integer is contained within the set of values of an
enumeration? Is there a way to do this?

Thanks,

JG

#include <stdio.h>

int main() {
enum { A = 1, B = 2 } foo;
foo = 3;
printf("%d\n", foo);
}

output: 3
 
F

Frederick Gotham

John Goche:
#include <stdio.h>

int main() {
enum { A = 1, B = 2 } foo;
foo = 3;
printf("%d\n", foo);
}

output: 3


I'm not quite sure how accurate it is, but Bjarne Stroustrup gave an
explanation of this before. In order to determine the highest value you can
store in an enum, you:

(1) Take the largest number which exists in the definition of the enum
(i.e. B = 2).
(2) Count the amount of bits needed to represent that number.
(3) Sets all the bits to yield the max value.

This would imply that the max value for your enum is 3 (i.e. 11 in binary).
 
I

Ian Collins

John said:
Hello,

The following program compiler and runs fine under gcc and produces
the output 3. However, I am not sure whether such behavior is legal.

Enums are broken (not proper types) in C, so it is legal to assign a int
to an enum.
 
E

Eric Sosman

Frederick said:
John Goche:





I'm not quite sure how accurate it is, but Bjarne Stroustrup gave an
explanation of this before. In order to determine the highest value you can
store in an enum, you:

(1) Take the largest number which exists in the definition of the enum
(i.e. B = 2).
(2) Count the amount of bits needed to represent that number.
(3) Sets all the bits to yield the max value.

The recipe doesn't work for (e.g.)

enum { LOW = -100, HIGH = 1 } x;
 
K

Keith Thompson

Ian Collins said:
Enums are broken (not proper types) in C, so it is legal to assign a int
to an enum.

Well, that depends on what you mean by "broken" and/or "proper".

An enumerated type is a distinct type, but there's an implicit
conversion between any enum type and any integer type, just as there
is between any two integer types, or between an integer type and a
float type. An enumeration *constant* is of type int, not of the
enumerated type.

C99 6.7.2.2 says:

Each enumerated type shall be compatible with char, a signed
integer type, or an unsigned integer type. The choice of type is
implementation-defined, but shall be capable of representing the
values of all the members of the enumeration.

Since the constants are of type int, there probably wouldn't be much
point in making an enumerated type bigger than int, but that's up to
the compiler.
 
F

Frederick Gotham

Ian Collins:
Enums are broken (not proper types) in C, so it is legal to assign a int
to an enum.


Ah yes, I must have missed that part of the Standard.
 
E

Eric Sosman

John said:
Hello,

The following program compiler and runs fine under gcc and produces
the output 3. However, I am not sure whether such behavior is legal.

It's legal, unfortunately. C's enum types are not really
"enumerations" of the kind some other languages offer, but just
integers. The compiler gets to choose any flavor of integer it
wants (unsigned short, signed char, ...), so long as the chosen
flavor can handle all the enum's named values. Thereafter, the
enum variable just acts like an integer variable of the chosen
type, and any value that would be legal for a plain integer of
that type is also legal for the enum variable.

Occasionally this freedom can be exploited usefully, as in

enum font_flags = { DEFAULT = 0,
BOLD = 1, ITALIC = 2, UNDERLINED = 4,
REVERSEVIDEO = 8, BLINKING = 16 };
...
enum font_flags style = DEFAULT;
if (important_message)
style |= BOLD;
if (annoy_the_viewer)
style |= BLINKING;
display_string ("Hello, world!", style);
In particular, as a related question, how would I go about checking
that a supplied integer is contained within the set of values of an
enumeration? Is there a way to do this?

C itself offers no way to do this. Some compilers in some
situations may issue warnings for legal but "suspicious" uses of
enums, but the language is of little help. The language also offers
no answer to "What are the largest and smallest declared values for
some enum type?", nor even "What are the largest and smallest possible
values for some enum type?" -- and if you want to do "Iterate over
all the declared values of this enum type," you're out of luck.

C's enums have little "power" and few worthwhile uses.
 
I

Ian Collins

Keith said:
Well, that depends on what you mean by "broken" and/or "proper".

An enumerated type is a distinct type, but there's an implicit
conversion between any enum type and any integer type, just as there
is between any two integer types, or between an integer type and a
float type. An enumeration *constant* is of type int, not of the
enumerated type.
We've had the argument before, but it's the implicit conversion from int
to enumerated type I consider broken. The set of values for the type is
there for a reason, being able to assign another value to an object of
that type just strikes me as wrong.

I prefer the C++ rules for enumerated types, mainly for the compile time
type checking when an enum is used as a function parameter.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top