By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,690 Members | 1,135 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,690 IT Pros & Developers. It's quick & easy.

Why is this allowed in C?

P: n/a
Is this allowed in ANSI C? My compiler says it's okay. If so, what is the
point of using enum instead of #define?

typedef enum
{
ONE = 1,

TWO = 2,

THREE = 3
} NUMBERS;
int main()
{
NUMBERS num = 5;

return 0;
}

TIA,
Bryan
Nov 14 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
Hi there,
Is this allowed in ANSI C? My compiler says it's okay. If so, what is the
point of using enum instead of #define?

typedef enum
{
ONE = 1,

TWO = 2,

THREE = 3
} NUMBERS;
int main()
{
NUMBERS num = 5;

return 0;
}


NUMBERS is a type which can have the values of all enumeration constants
you specified in your enum (and all the values in between).
An enumeration does _not_ provide a means to specify a set of values
which variables of the type can take on -- which probably is the
functionality you hoped for.
What you _can_ do, however, is using enumeration constants like symbolic
constants without having to care about the value. If you want to have,
for example, a means to distinguish between different cases but do not
care about the numbers behind the constants, you just use an enumeration

enum dc { firstcase, secondcase, thirdcase, fourthcase };

If you add a fifth case, you do not have to look for a new number to
assign to it but just use it.
Think of it as a convenient way of obtaining valid constants no two
of which are equal (if you do not wish it).

The discussion you find under
http://groups.google.com/groups?th=430152de91554ce3
may give you some additional ideas.

I like using C99 designated initializers along with enumerations,
e.g.

.....
/* Usage: Enter new sorting algorithm in list of algos after creating
** an enum entry.
*/

/* Enumeration of possible sorting algos */
typedef enum sortingalgos {START=-1,
selection,
insertion,
bubble,
shell,
quick,
LAST
} Counter;

/* Function pointer type for sorting algos */
typedef int (* MySortProcPtr) (int *, size_t);

/* Structure containing all algo information */
typedef struct {
char algochar; // I/O identifier
char *algoname; // Name to be printed
MySortProcPtr algofunc; // Function pointer
} SortingInfo;

/* Actual list; global for convenience */
static SortingInfo MyInfo[] = {
[selection] = {'s', "selection sort" , selectionsort},
[insertion] = {'i', "insertion sort" , insertionsort},
[bubble] = {'b', "bubble sort" , bubblesort},
[shell] = {'S', "Shell sort" , shellsort},
[quick] = {'q', "quick sort"
" (recursive,"
" middle of three,"
" insertion sort)" , quicksort}
};
.....

You loop with a Counter variable from START+1 to <END to search
for the identifiers, print the name, call the function but still
are able to handle exceptions by checking for the corresponding
enumeration constant. Using the designated initializer with the
constant makes sure that you never ever check for the wrong array
index...
Cheers
Michael

Nov 14 '05 #2

P: n/a
Bryan Bullard wrote:
Is this allowed in ANSI C? My compiler says it's okay. If so, what is the
point of using enum instead of #define?

typedef enum
{
ONE = 1,
TWO = 2,
THREE = 3
} NUMBERS;

int main()
{
NUMBERS num = 5;
return 0;
}


Yes, it's legitimate. An enum type is merely an
alias for some flavor of integer (the compiler gets to
choose which), and since 5 is within the range of every
integer type, the initialization is valid.

Some languages -- Pascal is one, IIRC -- provide true
enumerated types, in which the only valid values for a
NUMBERS object would be ONE, TWO, and THREE. But C's enum
types are less restrictive and (perhaps) less powerful:
All you get is the aforementioned alias for some kind of
integer plus suggestive names for the listed `int' values.

Are there advantages over #define'd constants? A few,
perhaps, but they're not very compelling. One is the
"automatic numbering" of the constants:

typedef enum { EINS = 1, ZWEI, DREI } ZAHLEN;

defines ZWEI as 2 and DREI as 3 without your needing to
state it explicitly -- not much of a savings in a list as
short as this one, but a convenience with larger lists.
Another (and this isn't really a C language issue) is that
some debuggers keep track of the constant names and will
display an `enum color' value as AQUAMARINE instead of 42;
I've never encountered a debugger that could do this with
#define'd constants.

See also Question 2.22 in the comp.lang.c Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

--
Er*********@sun.com

Nov 14 '05 #3

P: n/a
In <fX****************@newssvr11.news.prodigy.com> "Bryan Bullard" <re***@to.group.com> writes:
Is this allowed in ANSI C? My compiler says it's okay.
It's right. That's one of the reasons C is not considered a strongly
typed language.
If so, what is the point of using enum instead of #define?


1. Friendlier syntax, the compiler can do the numbering for you.

2. Preprocessor macros are gone after the preprocessing stage. This is
important in two occasions: you're using a debugger and you're
reading already preprocessed code. Both occur during program
debugging. It makes quite a difference between seeing an unadorned
arbitrary integer constant (say 3) and seeing an enumeration constant
like VALVE_OPEN.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union
Nov 14 '05 #4

P: n/a
In article <cj**********@news1brm.Central.Sun.COM>,
Eric Sosman <er*********@sun.com> wrote:
Are there advantages over #define'd constants? A few,
perhaps, but they're not very compelling. One is the
"automatic numbering" of the constants: Another (and this isn't really a C language issue) is that
some debuggers keep track of the constant names and will
display an `enum color' value as AQUAMARINE instead of 42;


Another is that some compilers will warn if a switch statement doesn't
cover all the cases of an enumeration. I've found that annoying
more often than useful, but maybe one day it will catch a bug I
would have spent hours tracking down otherwise.

-- Richard
Nov 14 '05 #5

P: n/a
Bryan Bullard wrote:
Is this allowed in ANSI C? My compiler says it's okay. If so, what is the
point of using enum instead of #define?

typedef enum { ONE = 1, TWO = 2, THREE = 3 } NUMBERS;
int main() { NUMBERS num = 5; return 0; }


This is valid. See the comp.lang.c FAQ, question 2.22:

http://www.eskimo.com/~scs/C-faq/q2.22.html

--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.
Nov 14 '05 #6

P: n/a

"Bryan Bullard" <re***@to.group.com> wrote in message
news:fX****************@newssvr11.news.prodigy.com ...
Is this allowed in ANSI C? My compiler says it's okay. If so, what is the point of using enum instead of #define?


....

Thanks everyone.
Nov 14 '05 #7

P: n/a
On 27 Sep 2004 18:42:59 GMT, Da*****@cern.ch (Dan Pop) wrote:
In <fX****************@newssvr11.news.prodigy.com> "Bryan Bullard" <re***@to.group.com> writes: <snip>
If so, what is the point of using enum instead of #define?


1. Friendlier syntax, the compiler can do the numbering for you.

And enums are restricted to ints, while #define'd macros can be long
etc., floating-point, strings, and indeed any (sequence of) tokens.
2. Preprocessor macros are gone after the preprocessing stage. This is
important in two occasions: you're using a debugger and you're
reading already preprocessed code. <snip>


Also, macros effectively prevent any other use of the same name, which
is why it is conventional to make (many) macros all-uppercase so you
won't accidently conflict. enum values are ordinary identifiers and do
not conflict with tags or locally-scoped variables or parameters.
Which again may be what you want, or not.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #8

P: n/a

"Dave Thompson" <da*************@worldnet.att.net> wrote in message
news:0q********************************@4ax.com...
Also, macros effectively prevent any other use of the same name, which
is why it is conventional to make (many) macros all-uppercase so you
won't accidently conflict. enum values are ordinary identifiers and do
not conflict with tags or locally-scoped variables or parameters.
Which again may be what you want, or not.


Locally-scoped variables are declaring as ordinary identifiers too.
Nov 14 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.