473,781 Members | 2,413 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=0x0 0000001,
OPERATION_2=0x0 0000002,
OPERATION_3=0x0 0000003,
...
};

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

Nov 14 '05 #1
9 6582
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=0x0 0000001,
OPERATION_2=0x0 0000002,
OPERATION_3=0x0 0000003,
...
};

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(sui t 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(sui t s);


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

--
"If you want to post a followup via groups.google.c om, 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=0x0 1,
OPERATION_2=0x0 2,
OPERATION_3=0x0 3
};

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.********@raum computer.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=0x0 1,
OPERATION_2=0x0 2,
OPERATION_3=0x0 3
};

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=0x0 0000001,
OPERATION_2=0x0 0000002,
OPERATION_3=0x0 0000003,
...
};

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.********@raum computer.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=0x0 1,
OPERATION_2=0x0 2,
OPERATION_3=0x0 3
};

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=0x0 0000001,
OPERATION_2=0x0 0000002,
OPERATION_3=0x0 0000003,
...
};

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=0x0 0000001,
OPERATION_2=0x0 0000002,
OPERATION_3=0x0 0000003,
...
};

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_Keit h) 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
1838
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
3591
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 amount of preprocessor directives used in these code. Can anyone please tell me how to actually use these preprocessor directives in a more professional way like selecting particular lines of code suited for some particular hardware etc...
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 for release version. In debug, I would like to use const declaration, as I found it more safer: for example: const uint8_t SPEED_FAST = 10; In release, I would like to use #define, as the constant value is
3
11670
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 {MAX_LIMIT=100}; then what is the basic difference? Is there any efficiency tradeoff between both the definitions.
3
1675
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
2149
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 identifier ID i use #ID. Thats ok, but what if i want to alter it a little. like if i have an identifier myID , and i want to generate an string MYID (or any other form) from it.
7
3363
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 parameters value and signal ID. Signal Id is used to get a user configurable parameter inside a configuration file, which depends on the type of switch. I have implemented it as under. Please ignore those magic numbers as I have mimized logic to...
6
4233
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
9636
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9474
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
10075
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9931
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8961
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7485
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5373
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5504
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3632
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.