473,738 Members | 11,146 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

To const or to enum?

Any opinions or comments on the following? I don't say it below, but I came
out on the side of using enumerations over static constants.

/* I'm trying to figure out the pros and cons of using static const
* int class members as opposed to using enumerations to accomplish a
* similar goal. The use of static constants seems more explicit and
* obvious to me. Unless I assign values to the enumerators, the
* compiler will do it for me. This has the advantage of saving
* keystrokes and digital ink. It has the disadvantage that I have to
* calculate the actual numerical value if I want to know what it
* is. With static constants, it is right there poking you in the eye.
*
* Enumerations support a rudimentary form of type checking. It may be
* useful, but possibly also deceptive. Basically any value that fits
* in the storage location used by the compiler to hold the
* enumerators will convert to the enumeration type, even if it is not
* a value of any of the enumerators. That can be useful for bounding
* a range of values, but it may also lead to a false impression that
* you are using a 'type-safe' value.
*
* The type checking can keep me honest if I want to be. That is, if
* I use the type name as an indicator that a given parameter is
* intended to be of that enumeration type, I can use the enumerators
* by name without explicit type conversions of the form Type(val).
*
* An example of where public static integral constants are used is in
* the w3c DOM recommendations . They serve as a form of poor-man's
* type checking. Each node type is assigned an integral constant
* value with an associated name. The base type of all nodes holds the
* definitions of these constants, and each derived node is assigned
* a named constant identical to one of those named in the baseclass.
*
* A purist may argue that static_cast, or dynamic_cast should be used
* instead, but static_cast only works for types known at compile
* time, and dynamic_cast incurs overhead beyond that of using a
* statically bound integral constant. I may be incorrect regarding
* this last point, but I'm pretty sure of it.
*
*
*/

/*
http://xml.apache.org/xerces-c/Apach...BindingL2.html
*/

/*
DOMNode.hpp:
class DOMNode
{
public:
enum NodeType {
ELEMENT_NODE = 1,
ATTRIBUTE_NODE = 2,
TEXT_NODE = 3,
CDATA_SECTION_N ODE = 4,
ENTITY_REFERENC E_NODE = 5,
ENTITY_NODE = 6,
PROCESSING_INST RUCTION_NODE = 7,
COMMENT_NODE = 8,
DOCUMENT_NODE = 9,
DOCUMENT_TYPE_N ODE = 10,
DOCUMENT_FRAGME NT_NODE = 11,
NOTATION_NODE = 12,
};
*/

/*
* The following is code I created to test certan uses of const and
* enum. I'll be more than happy to see alternatives, or additional
* uses of these syntactic elements.
*/
#include <iostream>
class A {
public:

/*
* We can't use A::EA or A::x before they are declared.
* Therefore the constructor is placed after the declarations,
* which are, in the case, definitions.
*/
/*
A(const A::AE& ae=A::x )
{
if(ae > x)
{
std::cout << "ae > x \n";
}
}
*/

/* Concise, but ugly.*/
/*
static const int X=0,
Y=1,
Z=2;
*/

/* More verbose, but clearer */
static const int X=0;
static const int Y=1;
static const int Z=2;

/* More concise, but more obscure to the untrained eye.*/
enum AE {x,y,z};

/* Placed after declarations (definitions) so I can use them*/
A(const A::AE& ae=A::x )
{
if(ae > x)
{
std::cout << "ae > x \n";
}
}

void f(const AE& ae)
{
if(ae > x)
{
std::cout << "ae > x \n";
}
}

/* How to make a DOM to XML generator, or syntax checker.*/
void g(const AE& ae)
{
switch(ae)
{
case A::x: std::cout << "case A::x \n";
return;
case A::y: std::cout << "case A::y \n";
return;
case A::z: std::cout << "case A::z \n";
return;
}
}

void h(const AE& ae)
{
switch(ae)
{
case A::x: std::cout << "case A::x \n";
return;
case A::y: std::cout << "case A::y \n";
return;
case A::z: std::cout << "case A::z \n";
return;
}
}
};

void i(const A::AE& ae)
{
switch(ae)
{
case A::x: std::cout << "case A::x \n";
return;
case A::y: std::cout << "case A::y \n";
return;
case A::z: std::cout << "case A::z \n";
return;
}
}

int main()
{
A a;
a.f(A::x);
a.f(A::AE(A::Z) );
a.f(A::AE(5));
}

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #1
12 3422
"Steven T. Hatton" <su******@setid ava.kushan.aa> wrote in message
news:3O******** ************@sp eakeasy.net...
Any opinions or comments on the following? I don't say it below, but I came out on the side of using enumerations over static constants.

/* I'm trying to figure out the pros and cons of using static const
* int class members as opposed to using enumerations to accomplish a
* similar goal. The use of static constants seems more explicit and
* obvious to me. Unless I assign values to the enumerators, the
* compiler will do it for me. This has the advantage of saving
* keystrokes and digital ink. It has the disadvantage that I have to
* calculate the actual numerical value if I want to know what it
* is. With static constants, it is right there poking you in the eye.
Either the value is important, or it's not. If it is important, then it
should be specified in the code. If it is not, then just let the compiler
do the work. Most of the enumerations that I have unimportant values that I
have never needed to know or calculate by hand.
* Enumerations support a rudimentary form of type checking. It may be
* useful, but possibly also deceptive. Basically any value that fits
* in the storage location used by the compiler to hold the
* enumerators will convert to the enumeration type, even if it is not
* a value of any of the enumerators. That can be useful for bounding
* a range of values, but it may also lead to a false impression that
* you are using a 'type-safe' value.
The entire C++ language presents a false impression of type-safety. Once UB
behavior occurs, all sorts of problems may occur. Sure, someone could
accidentally put an invalid value in the enum, but then again, someone could
also walk off the end of an array and cause all sorts of damage, so I won't
be losing any sleep over an enum. The "false impression" can be cured with
a little education.

<snip> * An example of where public static integral constants are used is in
* the w3c DOM recommendations . They serve as a form of poor-man's
* type checking. Each node type is assigned an integral constant
* value with an associated name. The base type of all nodes holds the
* definitions of these constants, and each derived node is assigned
* a named constant identical to one of those named in the baseclass.
The quoted header uses an enum, not static integers. Are you referring to
something else, or did you mistype something?
* A purist may argue that static_cast, or dynamic_cast should be used
* instead, but static_cast only works for types known at compile
* time, and dynamic_cast incurs overhead beyond that of using a
* statically bound integral constant. I may be incorrect regarding
* this last point, but I'm pretty sure of it.
I don't know of any purists that would argue for using static_cast with
enums, but that's a matter of taste. That should work just fine. However,
you can't use dynamic_cast because it's an enum, and not a polymorphic type.

<snip> /* More concise, but more obscure to the untrained eye.*/
enum AE {x,y,z};

<snip>

I think you mean "more concise, but more obscure to someone who doesn't know
the very basics of C or C++." :-)

--
David Hilsee
Jul 22 '05 #2
Ian
Steven T. Hatton wrote:
Any opinions or comments on the following? I don't say it below, but I came
out on the side of using enumerations over static constants.
Each has its place.
/* I'm trying to figure out the pros and cons of using static const
* int class members as opposed to using enumerations to accomplish a
* similar goal. The use of static constants seems more explicit and
* obvious to me. Unless I assign values to the enumerators, the
* compiler will do it for me. This has the advantage of saving
* keystrokes and digital ink. It has the disadvantage that I have to
* calculate the actual numerical value if I want to know what it
* is. With static constants, it is right there poking you in the eye.
* How often do you have to know the numerical value? If you do, then
maybe an enum is not the correct option. In the DOM example you quote,
you will never (or at least I have never) have to know the numeric
value. An enum is what is says on the box, an enumeration - the value
don't matter.
* Enumerations support a rudimentary form of type checking. It may be
* useful, but possibly also deceptive. Basically any value that fits
* in the storage location used by the compiler to hold the
* enumerators will convert to the enumeration type, even if it is not
* a value of any of the enumerators. That can be useful for bounding
* a range of values, but it may also lead to a false impression that
* you are using a 'type-safe' value.
* No, it won't. The compiler will barf on an attempt to pass an int to a
function with an enum parameter.
* The type checking can keep me honest if I want to be. That is, if
* I use the type name as an indicator that a given parameter is
* intended to be of that enumeration type, I can use the enumerators
* by name without explicit type conversions of the form Type(val).
* ? It's not an indicator, it's a requirement!
* An example of where public static integral constants are used is in
* the w3c DOM recommendations . They serve as a form of poor-man's
* type checking. Each node type is assigned an integral constant
* value with an associated name. The base type of all nodes holds the
* definitions of these constants, and each derived node is assigned
* a named constant identical to one of those named in the baseclass.
* Don't forget these cam form IDL and Java bindings (there is (or at least
was) no C++ binding in the W3C specification). So the lowest common
denominator, const ints was used.
* A purist may argue that static_cast, or dynamic_cast should be used
* instead, but static_cast only works for types known at compile
* time, and dynamic_cast incurs overhead beyond that of using a
* statically bound integral constant. I may be incorrect regarding
* this last point, but I'm pretty sure of it.
*

When working with DOM, the dynamic_cast overhead tends to be trivial.
You have the choice of RTTI or the node type, again, remember this stuff
started as IDL, so it has to be language neutral.

Ian
Jul 22 '05 #3
"David Hilsee" <da************ *@yahoo.com> wrote in message
news:aZ******** ************@co mcast.com...
<snip>
* A purist may argue that static_cast, or dynamic_cast should be used
* instead, but static_cast only works for types known at compile
* time, and dynamic_cast incurs overhead beyond that of using a
* statically bound integral constant. I may be incorrect regarding
* this last point, but I'm pretty sure of it.
I don't know of any purists that would argue for using static_cast with
enums, but that's a matter of taste. That should work just fine.

However, you can't use dynamic_cast because it's an enum, and not a polymorphic

type.

After reading Ian's post, I realized that you were talking about
dynamic_cast being applied to the nodes in the DOM, not the enums
themselves. My mistake.

IMHO, the "purist" approach of using dynamic_cast doesn't buy you much. You
still wind up in a switch/case-like structure. I'm not even sure that
purists would normally argue for dynamic_cast. Most of the time, they argue
against it, opting for virtual functions instead. In this case, they might
argue for the visitor pattern, which may look better to some and confusing
to others.

--
David Hilsee
Jul 22 '05 #4
David Hilsee wrote:
"Steven T. Hatton" <su******@setid ava.kushan.aa> wrote in message
news:3O******** ************@sp eakeasy.net...
Any opinions or comments on the following? I don't say it below, but I came
out on the side of using enumerations over static constants.
...
* An example of where public static integral constants are used is in
* the w3c DOM recommendations . They serve as a form of poor-man's
* type checking. Each node type is assigned an integral constant
* value with an associated name. The base type of all nodes holds the
* definitions of these constants, and each derived node is assigned
* a named constant identical to one of those named in the baseclass.


The quoted header uses an enum, not static integers. Are you referring to
something else, or did you mistype something?


No. I was just speaking in abstract terms. Static binding means a binding
that occurs before execution. I should have been more careful to make the
distinction. Enumerators are not integral types as defined in ISO/IEC
14882:2003, nor are they declared static const. Nonetheless, from a
conceptual perspective they are virtually identical. I was actually
thinking in terms of the w3c IDE recommendation.

http://www.w3.org/TR/2004/REC-DOM-Le...finitions.html
interface Node {

// NodeType
const unsigned short ELEMENT_NODE = 1;
const unsigned short ATTRIBUTE_NODE = 2;
const unsigned short TEXT_NODE = 3;
const unsigned short CDATA_SECTION_N ODE = 4;
const unsigned short ENTITY_REFERENC E_NODE = 5;
const unsigned short ENTITY_NODE = 6;
const unsigned short PROCESSING_INST RUCTION_NODE = 7;
const unsigned short COMMENT_NODE = 8;
const unsigned short DOCUMENT_NODE = 9;
const unsigned short DOCUMENT_TYPE_N ODE = 10;
const unsigned short DOCUMENT_FRAGME NT_NODE = 11;
const unsigned short NOTATION_NODE = 12;

//...
}

There is no w3c DOM binding recommendation for C++. What I posted was
Apache's proposed DOM binding.
I don't know of any purists that would argue for using static_cast with
enums,
I intended it as an alternative to using enums. If you use dynamic_cast you
don't need the enums. See §12.2.5 of TC++PL(SE) for a discussion of the use
of type fields (enums or static constants in this discussion).
but that's a matter of taste. That should work just fine.
However, you can't use dynamic_cast because it's an enum, and not a
polymorphic type.
As I said, that incurs more overhead than the use of statically bound
constants.
<snip>
/* More concise, but more obscure to the untrained eye.*/
enum AE {x,y,z};

<snip>

I think you mean "more concise, but more obscure to someone who doesn't
know the very basics of C or C++." :-)


That is not what I meant. Understanding is one thing. familiarity another.
I've understood what an expression of that form means for over a decade.
But that doesn't mean that it would be as immediately recognizable as the
explicitly named static constants, or explicitly initialized enumerators.
The reason I use the w3c DOM as an example is because the numerical values
are explicitly specified. A programmer could not, for example, add an
enumerator to the beginning of the list above and remove the explicit
initializations without deviating from the interface specification.

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #5
David Hilsee wrote:
"David Hilsee" <da************ *@yahoo.com> wrote in message IMHO, the "purist" approach of using dynamic_cast doesn't buy you much.
You
still wind up in a switch/case-like structure. I'm not even sure that
purists would normally argue for dynamic_cast. Most of the time, they
argue
against it, opting for virtual functions instead.
Yes, but that only works if you are invoking a method on the object, not if
you are trying to determine what to do with the object as a parameter to a
function, etc.
In this case, they
might argue for the visitor pattern, which may look better to some and
confusing to others.


It depends on what you are trying to accomplish. One problem with building
all your smarts into the node and its derivatives is that it requires some
very convoluted inheritance to create any kind of recursive instantiation.
I have built a parser that consisted of nodes that thought for themselves.
But I had to feed it meaningful tokens one at a time.

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #6
"Steven T. Hatton" <su******@setid ava.kushan.aa> wrote in message
news:Cd******** ************@sp eakeasy.net...
<snip>
In this case, they
might argue for the visitor pattern, which may look better to some and
confusing to others.
It depends on what you are trying to accomplish. One problem with

building all your smarts into the node and its derivatives is that it requires some
very convoluted inheritance to create any kind of recursive instantiation.
I have built a parser that consisted of nodes that thought for themselves.
But I had to feed it meaningful tokens one at a time.


I'm not sure I understand what you're saying. I was just pointing out that
the dynamic_cast could be eliminated with the visitor pattern, and that
might be supported by purists. I don't understand why that means the node
"thinks for itself" or why that means you have to feed it "one at a time."
For the visitor pattern, the node just has to override one member function
with a simple implementation (void accept(Visitor * p){p->visit(this);}) .
What are you saying is the issue that results from this?

BTW, I'm not a huge fan of the visitor pattern. I was just pointing out
what some people might prefer.

--
David Hilsee
Jul 22 '05 #7
"Steven T. Hatton" <su******@setid ava.kushan.aa> wrote in message
news:uO******** ************@sp eakeasy.net...
David Hilsee wrote: <snip>
I think you mean "more concise, but more obscure to someone who doesn't
know the very basics of C or C++." :-)


That is not what I meant. Understanding is one thing. familiarity

another. I've understood what an expression of that form means for over a decade.
But that doesn't mean that it would be as immediately recognizable as the
explicitly named static constants, or explicitly initialized enumerators.
The reason I use the w3c DOM as an example is because the numerical values
are explicitly specified. A programmer could not, for example, add an
enumerator to the beginning of the list above and remove the explicit
initializations without deviating from the interface specification.


Well, I meant that as a joke to poke fun at those who might find enums
strange or mildly confusing, but I am surprised that you would say that
enums without explicitly specified values are not immediately recognizable.
I learned about enums when I first learned C, I have never had to think
twice about them since then. To me, it is immediately recognizable, easily
understandable, and very familiar, even though I do not often use enums or
see them used in practice. I guess I just found them very intuitive and
simple.

--
David Hilsee
Jul 22 '05 #8

"Steven T. Hatton" <su******@setid ava.kushan.aa> wrote in message
news:3O******** ************@sp eakeasy.net...
Any opinions or comments on the following? I don't say it below, but I came out on the side of using enumerations over static constants.

/* I'm trying to figure out the pros and cons of using static const
* int class members as opposed to using enumerations to accomplish a
* similar goal. The use of static constants seems more explicit and
* obvious to me. Unless I assign values to the enumerators, the
* compiler will do it for me. This has the advantage of saving
* keystrokes and digital ink. It has the disadvantage that I have to
[...]
I.m.o the problem with enums is that they get abused.
One should be able to change the position and values of an enum entry
at any time without breaking code.

An enum is indeed a type and has many advantages over const variables.
Enums look like classes but do not profit from the implicit namespace that a
class has, in other words:
EColType::Red
is illegal. This is unfortunate. Yet ms vc7 will eat accept!

The type of an enum member is not known and should never be assumed.

Here is what I try to adhere to when using enums:

1. Prefix every enum member with the enum name unless the enum
is part of a class in which case it "can" be left out:

enum EColorType
{
EColTypeInvalid ,
EColTypeRed,
EColTypeBlue
};

This is necessary because enum members have global scope wether we
like it or not. In any sizeable project, good descriptive names get very
quickly used up.

2. Never ever cast an enum member.
Allways provide a complete (however large) switch to map enum
members to and from other context appropriate values.
This mapping is vital because this is the place where published
values (as read from and written to a data base) are maintained and
de-coupled from the enum.

3. Never ever use enum members in loop indexes and loop limits.

Regards,
Conrad Weyns
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org


Jul 22 '05 #9
Conrad Weyns wrote:

Here is what I try to adhere to when using enums:

1. Prefix every enum member with the enum name unless the enum
is part of a class in which case it "can" be left out:

enum EColorType
{
EColTypeInvalid ,
EColTypeRed,
EColTypeBlue
};

Your prefix "EColType" differs from the enum name, but I guess that's a
typo...? Still, shouldn't we use a little namespace instead? Like
this:

namespace Color
{
enum Type
{
Invalid,
Red,
Blue
};
};
Regards,

Niels Dekker
www.xs4all.nl/~nd/dekkerware
Jul 22 '05 #10

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

Similar topics

7
1936
by: mcdonamw | last post by:
This may sound like a stupid stupid question and I figure it would b more "general" than pertaining to a specific Language. I'm using vb.net and I have a bunch of Const values in my program. can use them obviously by placing their names in place of values, henc the ideal behind using Const. My question is... is there a way to get the actual Variable name for specific value that is returned to me?
3
12367
by: Ajax Chelsea | last post by:
can not the "static const int" be replaced by "static enum" anywhere? is it necessary that define special initialization syntax for "static const int"?
2
1700
by: WindAndWaves | last post by:
Can anyone tell me when to use ENUM and when to use Public Const? TIA - Nicolaas
2
4079
by: shawn | last post by:
As far as i know, keyword "const" is invented to replace "define" identifier. But ... test1.c ------------------------------ #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) {
6
1501
by: shawn | last post by:
test1.c ------------------------------ #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { const int MAX_CHAR_NUM=10; char name="Computer"; printf("My name is %s.\n", name);
7
7007
by: Peng Yu | last post by:
I'm not very clear about when to use #define and when to use const? #define number 4 const int number = 4; If I just want to define a global constant, which way of the above is better? Thanks, Peng
4
21709
by: Bilgehan.Balban | last post by:
Hi, The following code: #include <stdio.h> // const int const_asize = 10; #define define_asize = 10; int array = {1,2,3,4,5,6,7,8,9,0};
11
1792
by: Szabolcs Nagy | last post by:
is there a reason why const is not compile-time constant? the usual example, where it'd be nice is array declaration: const int N = 4; float arr or one may want to use an enum for indices: enum index {a,b,c,d,N}; float arr
16
1921
by: arnuld | last post by:
I have declared an int as const but compiler still says that it is not a const: include <stdio.h> #include <stdlib.h> int main() { const int MAXSIZE = 100;
0
8969
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
8788
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,...
0
9335
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9208
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
8210
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...
0
4825
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3279
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 we have to send another system
2
2745
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2193
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.