473,499 Members | 1,721 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

preprocessor and enum

Hi all,
We can define some magic number with #define:

#define OPERATION_1 0x00000001
#define OPERATION_2 0x00000002
#define OPERATION_3 0x00000003
....

We can also do that with enum:
enum OPERATION
{
OPERATION_1=0x00000001,
OPERATION_2=0x00000002,
OPERATION_3=0x00000003,
...
};

What make you prefer preprocessor? What make you prefer enum? Any
experience support that?

Nov 14 '05 #1
9 6557
On 2 Mar 2005 20:08:38 -0800, "ccwork" <cc****@hotmail.com> wrote:
Hi all,
We can define some magic number with #define:

#define OPERATION_1 0x00000001
#define OPERATION_2 0x00000002
#define OPERATION_3 0x00000003
...

We can also do that with enum: [...] What make you prefer preprocessor? What make you prefer enum?


Preprocessor is find with C, but should be avoided as a #define does not
have any knowledge of context and can mess things up if you don't expect
them to. (e.g. a header file defines the macro begin, which clobbers local
variable definitions.)
Nov 14 '05 #2

On Wed, 2 Mar 2005, ccwork wrote:

We can define some magic number with #define:

#define OPERATION_1 0x00000001
#define OPERATION_2 0x00000002
#define OPERATION_3 0x00000003
...

We can also do that with enum:
enum OPERATION
{
OPERATION_1=0x00000001,
OPERATION_2=0x00000002,
OPERATION_3=0x00000003,
...
};

What make you prefer preprocessor? What make you prefer enum? Any
experience support that?


What I say: Enums are the way to go. They give you all the benefits
of a compile-time constant, plus the benefits of the language's type
checking.
What I do: #define, #define, #define. Why? Because #defines are
easier to type. They don't require you to insert = signs everywhere,
or to count commas. (Yes, you just need to stick a comma after each
enumeration value --- but that's still a lot of extra typing, even if
it is mindless.)
There's another dumb reason I use #defines over enums: I don't have
to think about capitalization. #defined constants in C code are ALL_CAPS,
always. Enumeration constants... well, I'd have to think about that.
I'd probably lower_case enum values in most cases. But the important
thing is, I'd have to think about it. With #defines, there's a default
style that everyone knows by heart, so it's one less thing to worry
about.
Another dumb reason: Enum definitions define a new "type." Which I
usually feel deserves a name, such as

enum suit {
Hearts, Spades, Clubs, Diamonds,
};

Now, suppose I write a function that takes a suit as a parameter. Do
I write

void pick_a_card(suit s);

or do I write

void pick_a_card(int s);

? With #defines, there's no decision to make. No new type, no tricky
style decisions.

So there you have it --- I recommend 'enum' in theory, but when it
comes to actual coding (of relatively tiny stuff, I must add), I almost
always use '#define' instead, because it means fewer time-consuming
style decisions for me.

HTH, but get a second opinion,
-Arthur
Nov 14 '05 #3
"Arthur J. O'Dwyer" wrote:
.... snip ... Another dumb reason: Enum definitions define a new "type." Which I
usually feel deserves a name, such as

enum suit {
Hearts, Spades, Clubs, Diamonds,
};

Now, suppose I write a function that takes a suit as a parameter.
Do I write

void pick_a_card(suit s);


Which would be wrong. No suit type has been defined, only "enum
suit".

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #4
there is a small difference when it comes to compilation.
imagine you have a small number of OPERATIONS that would
fit into one byte.
your declaration would then look like this :

#define OPERATION_1 0x01
#define OPERATION_2 0x02
#define OPERATION_3 0x03

or

enum OPERATION
{
OPERATION_1=0x01,
OPERATION_2=0x02,
OPERATION_3=0x03
};

now imagine you compile the statements

unsigned char OP;
....
if(OP == OPERATION_1) { DoSomething() }

for an 8 bit processor (they are still used in embedded systems)
the comparison would take 3 assembler statements (2 byte compares
and a conditional jump) for the enum version, cause the compiler
would typecast OP to int. (typecasts always to the bigger type)
it would only take 2 assembler statements (1 compare, 1 conditional
jump) for the #define version.
Nov 14 '05 #5
d.********@raumcomputer.com wrote:
there is a small difference when it comes to compilation.
imagine you have a small number of OPERATIONS that would
fit into one byte.
your declaration would then look like this :

#define OPERATION_1 0x01
#define OPERATION_2 0x02
#define OPERATION_3 0x03

or

enum OPERATION
{
OPERATION_1=0x01,
OPERATION_2=0x02,
OPERATION_3=0x03
};

now imagine you compile the statements

unsigned char OP;
...
if(OP == OPERATION_1) { DoSomething() }

for an 8 bit processor (they are still used in embedded systems)
the comparison would take 3 assembler statements (2 byte compares
and a conditional jump) for the enum version, cause the compiler
would typecast OP to int. (typecasts always to the bigger type)
it would only take 2 assembler statements (1 compare, 1 conditional
jump) for the #define version.


The compiler is perfectly at liberty to implement the enum comparison
the "short way" if it so wishes. I presume C compilers for 8-bit
machines are very likely to make wishes of that kind.

--
Chris "electric hedgehog" Dollin
Nov 14 '05 #6
ccwork wrote:
Hi all,
We can define some magic number with #define:

#define OPERATION_1 0x00000001
#define OPERATION_2 0x00000002
#define OPERATION_3 0x00000003
...

We can also do that with enum:
enum OPERATION
{
OPERATION_1=0x00000001,
OPERATION_2=0x00000002,
OPERATION_3=0x00000003,
...
};

What make you prefer preprocessor? What make you prefer enum? Any
experience support that?


enums are the way to go I believe. They allow the compiler some more
information, which it can in turn use to help you out.

Example:

switch (foo) {
case OPERATION_1:
...
break;
case OPERATION_2:
...
break;
}

If foo is an int, that can't get you a diagnostic. If foo is an enum
the compiler (e.g. gcc with -Wall) might be able to give you something
like this:
foo.c:20: warning: enumeration value `OPERATION_2' not handled in switch

I like that. If I have a switch that doesn't have a default and doesn't
cover all the enumerated cases I think it is broken, nice that the
compiler can detect it. There may be other cases where the compiler
can do useful things given the knowledge that a value is an enumeration,
not sure though.

-David
Nov 14 '05 #7
d.********@raumcomputer.com wrote:
there is a small difference when it comes to compilation.
imagine you have a small number of OPERATIONS that would
fit into one byte.
your declaration would then look like this :

#define OPERATION_1 0x01
#define OPERATION_2 0x02
#define OPERATION_3 0x03

or

enum OPERATION
{
OPERATION_1=0x01,
OPERATION_2=0x02,
OPERATION_3=0x03
};

now imagine you compile the statements

unsigned char OP;
...
if(OP == OPERATION_1) { DoSomething() }

for an 8 bit processor (they are still used in embedded systems)
the comparison would take 3 assembler statements (2 byte compares
and a conditional jump) for the enum version, cause the compiler
would typecast OP to int.
If the compiler does that then the optimiser is not very good. It should
see at compile time whether OPERATION_1 is within the range of OP and if
it isn't eliminate the code and if it is do a test of the byte against
the requisite value.
(typecasts always to the bigger type)
it would only take 2 assembler statements (1 compare, 1 conditional
jump) for the #define version.


Actually, 0x01 also has a type of int, so if the compiler does not
optimise the comparison as described above you still have the problem.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #8


ccwork wrote:

Hi all,
We can define some magic number with #define:

#define OPERATION_1 0x00000001
#define OPERATION_2 0x00000002
#define OPERATION_3 0x00000003
...

We can also do that with enum:
enum OPERATION
{
OPERATION_1=0x00000001,
OPERATION_2=0x00000002,
OPERATION_3=0x00000003,
...
};

What make you prefer preprocessor? What make you prefer enum? Any
experience support that?


I like to use:
typedef enum {
XXX=0,
YYY,
ZZZ,
...
} MyEnumType_t;

This makes it easy do define a large number of UNIQUE values - using
#define to define 20 or 30 values may seem ok, but you could easily
define two to be the same value.
(Note - I only ever specify the first value for the enum).

By using a typedef, I avoid the problem mentioned by Mr. O'Dwyer:
foo( MyEnumType_t arg );

--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Common User Interface Services
M/S 2R-94 (206)544-5225
Nov 14 '05 #9
"ccwork" <cc****@hotmail.com> writes:
Hi all,
We can define some magic number with #define:

#define OPERATION_1 0x00000001
#define OPERATION_2 0x00000002
#define OPERATION_3 0x00000003
...

We can also do that with enum:
enum OPERATION
{
OPERATION_1=0x00000001,
OPERATION_2=0x00000002,
OPERATION_3=0x00000003,
...
};

What make you prefer preprocessor? What make you prefer enum? Any
experience support that?


I consider the use of enum this way to be a trick; it creates a
superfluous type when all that's needed is a set of constants.

However, it's a fairly common idiom, and I have no problem with using
it. I'd probably drop the tag (since you never want to use the type)
and add a comment explaining the purpose of the declaration, something
like:

/*
* This enum declaration is intended only to create a set of
* constants; the type itself is not used.
*/
enum {
OPERATION_1 = 0x00000001,
OPERATION_2 = 0x00000002,
OPERATION_3 = 0x00000003,
...
};

One drawback is that it can only create constants of type int.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
1815
by: SerGioGio | last post by:
Hello, Is there a way to #define a (set of) macro that will turn: FUNC(a)(b)(c) into: func(a, b, c) regardless of the number of parameters? i.e: FUNC(a)(b)(c) ---> func(a, b, c)
13
3548
by: seemanta dutta | last post by:
Greetings C gurus, I have used preprocessor directives since a very long time. But whenever I see some professional piece of C code, the linux kernel for example, I get literally confused by the...
6
540
by: francesco | last post by:
I'm programming an embedded system, on a Fujitsu microcontroller. Stated that I'm not sure about constants optimization, I'm trying to declare constants in two ways, one for debug version and one...
3
11652
by: ashwani | last post by:
Hi Can any one tell me the difference between preprocessor macros like #define and enum. If i want to define MAX_LIMIT=100 as preprocessor macro as #define MAX_LIMIT 100 or if i define enum...
3
1658
by: R Pradeep Chandran | last post by:
Hi All, Short version: Is it possible to write macros to expand the following DATAGROUP(abc) ELEMENT(xyz) ENDDATAGROUP to
10
2115
by: abir | last post by:
Hi, This is not strictly a C++ language question. Is there any way to form a string from an identifier with the preprocessor with some operations ? i.e to say to make a string from an...
7
3346
by: Rohit | last post by:
Hi, I am working on a switch module which after reading voltage through a port pin and caterogizing it into three ranges(open,low or high), passes this range to a function switch_status() with...
6
4209
by: =?ISO-8859-2?Q?Boris_Du=B9ek?= | last post by:
Hi, I have trouble defining a macro - see the following code: #define LETTER_STRAIGHT(let) let = L'#let' enum Letter { LETTER_STRAIGHT(A), LETTER_STRAIGHT(B), LETTER_STRAIGHT(C),
0
7006
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7215
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6892
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7385
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5467
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4597
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3096
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1425
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
661
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.