Question about "enums"

M

mdh

In one of the answers to a K&R exercise, the first couple of lines are:

enum loop { NO, YES};
enum loop okloop=YES;

I get the first line, but not the second.

Sorry about the LOL question.

Thanks in advance
 
I

Ian Collins

mdh said:
In one of the answers to a K&R exercise, the first couple of lines are:

enum loop { NO, YES};
enum loop okloop=YES;
oklopp us a variable of the enum type loop, so you can assign either NO
or YES to it.
 
M

mdh

Ian Collins wrote:

oklopp us a variable of the enum type loop, so you can assign either NO
or YES to it.

It must be late or too much C :)

I guess what I am missing is what the:

enum loop { YES,NO}

then does?

I thought that the idea behind this was to assign an integer to the
YES, NO? ( In this case 0 and 1?)

Then why not simply use the terms "YES" and "NO"?

Thanks in advance?
 
C

CBFalconer

mdh said:
In one of the answers to a K&R exercise, the first couple of lines
are:

enum loop { NO, YES};
enum loop okloop=YES;

I get the first line, but not the second.

Then separate the second line into its components:

enum loop okloop;

okloop = YES;

and the three lines are: type declaration, var declaration,
assignment.
 
I

Ian Collins

mdh said:
Ian Collins wrote:





It must be late or too much C :)

I guess what I am missing is what the:

enum loop { YES,NO}

then does?
An enum is a type, which in this case can have one of two values, YES
and NO.

Assigning any other value to a loop is undefined. Unfortunately C
compilers don't regard this as an error, which renders enums little more
than symbolic constants.
I thought that the idea behind this was to assign an integer to the
YES, NO? ( In this case 0 and 1?)

Then why not simply use the terms "YES" and "NO"?
you can,

int n = YES;

Is perfectly OK.
 
V

venkatesh

u can make use of okloop whereever u want "1"
if if is not that please correct me
 
I

Ian Collins

venkatesh said:
u can make use of okloop whereever u want "1"
if if is not that please correct me
What are you replying to? Please quote the context.

Assuming you are refereing to:

enum loop { NO, YES};
enum loop okloop=YES;

You would use loop whenever you wanted YES. Use an enum for what it is,
if you wanted a synonym for 1, use a const (unsigned) int.
 
B

Bill Pursell

Ian said:
An enum is a type, which in this case can have one of two values, YES
and NO.

Assigning any other value to a loop is undefined. Unfortunately C
compilers don't regard this as an error, which renders enums little more
than symbolic constants.

gcc gives a warning when you do a switch on an enum type, indicating
that you have failed to explicitely specify behavior for any of the
listed cases. I find that very useful.
 
I

Ian Collins

Bill said:
gcc gives a warning when you do a switch on an enum type, indicating
that you have failed to explicitely specify behavior for any of the
listed cases. I find that very useful.
But not with the following, which I've always considered a huge hole in
the C standard.

enum loop { NO, YES};
enum loop okloop=YES;

void f( enum loop v )
{
}

int main(void)
{
f( 42 );

okloop = 42;

return 0;
}
 
B

Bill Pursell

Ian said:
But not with the following, which I've always considered a huge hole in
the C standard.

enum loop { NO, YES};
enum loop okloop=YES;

void f( enum loop v )
{
}

int main(void)
{
f( 42 );

okloop = 42;

return 0;
}

Agreed. I've never written a compiler, but it strikes me that that
should be a fairly simple warning to emit. Does anyone know why such
warnings are not given?
 
M

mdh

Ian said:
Assigning any other value to a loop is undefined. Unfortunately C
compilers don't regard this as an error, which renders enums little more
than symbolic constants.


Is this what you mean?

enum months{Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec};
enum months mymonths=14; / * Should really raise an outofbounds
exception ? */

printf("I have chosen month %d", mymonths); /* prints 14 */
 
G

Guest

Ian said:
What are you replying to? Please quote the context.

Assuming you are refereing to:

enum loop { NO, YES};
enum loop okloop=YES;

You would use loop whenever you wanted YES. Use an enum for what it is,
if you wanted a synonym for 1, use a const (unsigned) int.

A const int can't be used in constant expressions. I'll admit declaring
okloop as int in that example is probably not a good idea, but do you
have a problem with unnamed enums used to define constants too?
 
I

Ian Collins

mdh said:
Ian Collins wrote:





Is this what you mean?

enum months{Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec};
enum months mymonths=14; / * Should really raise an outofbounds
exception ? */
Yes, it sure does in C++.
 
I

Ian Collins

Harald said:
A const int can't be used in constant expressions.

Another oversight that should have been fixed.
I'll admit declaring
okloop as int in that example is probably not a good idea, but do you
have a problem with unnamed enums used to define constants too?
No, it's the only tidy workaround for the previous oversight.
 
T

Thad Smith

Ian said:
mdh wrote:

An enum is a type, which in this case can have one of two values, YES
and NO.

Assigning any other value to a loop is undefined. Unfortunately C
compilers don't regard this as an error, which renders enums little more
than symbolic constants.

Assigning values other than the constants declared in the enumeration
are not necessarily undefined by the C Standard. The implementation
must assign the enum to an integer type which will hold all the
enumeration constants. It can hold other integer values as well. An
enum type is basically an integer type and can be used as such.

Having said that, I think it is wise, as a good engineering practice, to
use an enum type to hold only the explicitly declared values.
 
I

Ian Collins

Thad said:
Assigning values other than the constants declared in the enumeration
are not necessarily undefined by the C Standard. The implementation
must assign the enum to an integer type which will hold all the
enumeration constants. It can hold other integer values as well. An
enum type is basically an integer type and can be used as such.

Having said that, I think it is wise, as a good engineering practice, to
use an enum type to hold only the explicitly declared values.
Can you think of any good reason for not enforcing that practice?
 
T

Thad Smith

Ian said:
Thad Smith wrote:

Can you think of any good reason for not enforcing that practice?

Attempts to assign anything other than an enumeration constant defined
for the associated enumeration type or another enumeration variable of
the same type would be a useful compiler or lint warning. Refusing to
translate in such cases would make the compiler non-conforming.
 
I

Ian Collins

Thad said:
Attempts to assign anything other than an enumeration constant defined
for the associated enumeration type or another enumeration variable of
the same type would be a useful compiler or lint warning. Refusing to
translate in such cases would make the compiler non-conforming.
Maybe this is a topic for comp.std.c, I still think the C standard is
broken in this instance.
 
K

Keith Thompson

Ian Collins said:
Thad Smith wrote: [snip]
Attempts to assign anything other than an enumeration constant defined
for the associated enumeration type or another enumeration variable of
the same type would be a useful compiler or lint warning. Refusing to
translate in such cases would make the compiler non-conforming.
Maybe this is a topic for comp.std.c, I still think the C standard is
broken in this instance.

I wouldn't say it's broken. The design of enumerated types isn't
ideal, but I don't think it's possible to fix it (though it would be
possible to invent a new feature that doesn't have the drawbacks of
the current types).

For example:

enum foo { a, b };
enum foo e;
int i = 2;
e = i;

In this case, obj is an object of type "enum foo", and the value of i
is assigned to it. The value being assigned doesn't match any of the
enumerators of the type, but there's no way in general to detect this
at compilation time.

If it's going to be detected at run time, you need to introduce an
entire mechanism for detecting run time errors, something that C
doesn't currently have. And for this particular check, a simple range
check is insufficient; consider replacing the type declaration above
with:

enum foo { a = 1, b = 37 };

C's enumerated types really don't provide much more than a set of
named constants. There are other languages that have more type-safe
enumerated types (Pascal and Ada, for example), but I don't think it's
likely that C's enumerated types can be significantly improved without
breaking existing code (or the language itself).

If you can come up with a proposal, though, by all means go for it.
 

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,755
Messages
2,569,536
Members
45,017
Latest member
GreenAcreCBDGummiesReview

Latest Threads

Top