Global constants against enumeration

In terms of coding practice, in what contexts do global constants prefer enumeration and vice versa?

For example, suppose I need a way to express various tile sprites globally. I could do ...

const int TILE_RED = 0; const int TILE_GREEN = 1; const int TILE_BLUE = 2; const int TILE_CENTER = 3; const int TILE_TOP = 4; const int TILE_TOPRIGHT = 5; const int TILE_RIGHT = 6; const int TILE_BOTTOMRIGHT = 7; const int TILE_BOTTOM = 8; const int TILE_BOTTOMLEFT = 9; const int TILE_LEFT = 10; const int TILE_TOPLEFT = 11; 

or

 enum Tile { TILE_RED, TILE_GREEN, TILE_BLUE, TILE_CENTER, TILE_TOP, TILE_TOPRIGHT TILE_RIGHT, TILE_BOTTOMRIGHT, TILE_BOTTOM, TILE_BOTTOMLEFT, TILE_LEFT, TILE_TOPLEFT }; 

Obviously, we prefer constants and enums for macros, but what about when it comes to constants and enums? What situations prefer what? I read here that permanent objects pose a small risk of making your program slower, but I would like to hear the thoughts of others.

I used this example, in particular because it is a large set of related objects - pajamas for cats to list.

+3
c ++
source share
6 answers

The best part about the enumerations is that they are portable between C and C ++, and const elements cannot be used in C in all places that you may like (for example, array declarations). Therefore, for headings that I would like to work in C or C ++, I tended to use enumerations, preferring const declarations or macro definitions. I actually used them, regardless of whether the header is for C ++ only or not (one smaller solution that I should think about).

Having an enumeration type is ambiguous - this is not a problem very often - if you are overloaded based on various different types of integrals, you will have enumeration problems, in which case const objects are likely to be better. But I can’t remember the last time I needed a different behavior for different types of the same number (i.e., to process 5U differently than 5 or 5L ). I think that the type of overload is really only observed in puzzle / interview problems, or is it code that will generate errors in any case, whether you use enumerations or not.

So, on the bottom line, I preferred enumerations, but good luck for your staff to stop using macros. Using macros for named constants is quite well rooted in the C / C ++ culture, and even though they are heavily polluting the namespace, there are not enough real text problems to convince many people to even think about changing habits.

+4
source share

The two related advantages of enumerations are their self-documenting nature and the fact that they keep the namespace clearer . Basically, enumerations are similar to bundles of semantically related constants, within their own namespace. Using the enumerations in intefaces, you implicitly specify which set of values ​​will be expected.

Edit: Bugfix! (I have been doing too much C # lately, and not enough C / C ++!)
With C and C ++, identifiers in an enumeration are encompassed as regular variables and constants, and therefore must be different from any other identifier in the same scope, including identifiers in other enumeration lists. This differs from more modern languages, where enumeration introduces its own namespace. The notion that C / C ++ enumeration helps with namespace preservation is incorrect. Thank you Michael Burr for pointing this out.

The main disadvantage of enumerations is that they are not so easily portable . The constant type and value are uniquely defined, there is less clarity with the enumerations.

+4
source share

Use enumerations when the constant value is either not important or sequential, as in your example.

Use constants if you need special constant values ​​assigned to an identifier.

+2
source share

The biggest advantage of enumeration is that it can be enforced by the compiler, but this is not so with the constant.

+1
source share

Implicit enumerations can cause some platform compatibility issues and are also not type safe. Global constants are type safe and usually preferred. However, if you lose sight of this, enums are usually used for related things and constants for more unrelated things.

An example when you will use enumerations:

 enum Colors { COLOR_RED=0xFF0000, COLOR_GREEN=0x00FF00, COLOR_BLUE=0x0000FF } 

An example of using global constants:

 volatile const void *VRAM=0x00FC0000; 

Finally, my advice is that if you really care about platform compatibility, use global constants.

0
source share

If there is no particular reason for backward compatibility, I prefer forward compatibility. In this case, the use of global constants is no longer dependent on the compiler, but I vote for the enumerations for several reasons:
1. consts can have different types. All that is required is a poor search - a replacement when you want to replace the type of your listing. This can lead to some unexpected consequences (consider signed / unsigned and the size of the value). in transfers one type is applied.
2. In C ++ 0x, strongly typed enumerations are introduced. There are several implementations for this already in C ++.
3. transfers, IMHO, it is very difficult to write in an unclear way. You cannot say this on consts (scattered across multiple files, etc.).

BTW. If you use const, I prefer to use static constants inside the class (rather than global).

0
source share

All Articles