Reputation: 170489
The typical way to define an integer constant to use inside a function is:
const int NumbeOfElements = 10;
the same for using within a class:
class Class {
...
static const int NumberOfElements = 10;
};
It can then be used as a fixed-size array bound which means it is known at compile time.
Long ago compilers didn't support the latter syntax and that's why enums were used:
enum NumberOfElementsEnum { NumberOfElements = 10; }
Now with almost every widely used compiler supporting both the in-function const int
and the in-class static const int
syntax is there any reason to use the enum for this purpose?
Upvotes: 22
Views: 11608
Reputation: 101565
The reason is mainly brevity. First of all, an enum
can be anonymous:
class foo {
enum { bar = 1 };
};
This effectively introduces bar
as an integral constant. Note that the above is shorter than static const int
.
Also, no-one could possibly write &bar
if it's an enum
member. If you do this:
class foo {
static const int bar = 1;
}
and then the client of your class does this:
printf("%p", &foo::bar);
then he will get a compile-time linker error that foo::bar
is not defined (because, well, as an lvalue, it's not). In practice, with the Standard as it currently stands, anywhere bar
is used where an integral constant expression is not required (i.e. where it is merely allowed), it requires an out-of-class definition of foo::bar.
The places where such an expression is required are: enum
initializers, case
labels, array size in types (excepting new[]
), and template arguments of integral types. Thus, using bar
anywhere else technically requires a definition. See C++ Core Language Active Issue 712 for more info - there are no proposed resolutions as of yet.
In practice, most compilers these days are more lenient about this, and will let you get away with most "common sense" uses of static const int
variables without requiring a definition. However, the corner cases may differ, however, so many consider it to be better to just use anonymous enum
, for which everything is crystal clear, and there's no ambiguity at all.
Upvotes: 30
Reputation: 10808
There is a difference between those two. Enums don't have an adress as far as I know. static const ints do though. So if someone takes the adress of the const static int, casts away the const, he can modify the value (although the compiler might ignore the change because he thinks it's const). This is of course pure evil and you should not do it - but the compiler can't prevent it. This can't happen with enums.
And of course - if you (for some reason) need the adress of that const, you need the static const int.
In short - enum is an rvalue while const static int is an lvalue. See http://www.embedded.com/story/OEG20011129S0065 for more details.
Upvotes: 2
Reputation: 3150
Use of enum have one advantage. An enum type is a type, so if you define, for example:
enum EnumType { EnumValue1 = 10, EnumValue2 = 20 ... };
and you have a function like:
void Function1(EnumType Value)
the compiler checks that you are passing a member of the enum EnumType to the function, so only valid values for parameter Value would be EnumValue1 and EnumValue2. If you use constants and change the function to
void Function1(int Value)
the compiler checks that you are passing an int (any int, a constant, variable or literal) to the function.
Enum types are good for grouping related const-values. For only one const value, I do not see any advantage.
Upvotes: 7
Reputation: 2551
Well, the portability is a good reason for using enum. It is great, because you don't have to worry whether your compiler supports "static const int S = 10" or not...
Also, as far as I remember, static variable must be defined somewhere, as well as declared, and the enum value must be declared only.
Upvotes: 1
Reputation: 11028
The only reason for using the "enum hack" is that old compilers do not support in-class const definitions, as you say in your question. So, unless you suspect that your code will be ported to an old compiler, you should use const where const is due.
Upvotes: 6
Reputation: 94299
In your case, I'd use a constant as well. However, there are other cases where I might be adding other, related constants. Like this:
const int TextFile = 1; // XXX Maybe add other constants for binary files etc.?
In such cases, I use an enum right away with a single value, like this:
enum FileType {
TextFile = 1
// XXX Maybe add other values for binary files etc.?
}
The reason is that the compiler can then issue warnings when I'm using the constant value in switch expressions, as in:
FileType type;
// ...
switch ( type ) {
case TextFile:
// ...
}
In case I decide to add another constant value which is related to the existing value (a different type of file, in this example), virtually all compilers will issue a warning since the new value is not handled in the switch statement.
If I had used 'int' and constants instead, the compiler wouldn't have a chance to issue warnings.
Upvotes: 6
Reputation: 224049
Defining static constants directly in the class definition is a later addition to C++ and many still stick to the older workaround of using an enum
for that. There might even be a few older compilers still in use which don't support static constants directly defined in class definitions.
Upvotes: 10
Reputation: 57192
I think that there's no reason to use an enum, and that it's actually better to use a static const int
for this purpose, since an enum has its own type (even if implicitly convertible to an integer).
Upvotes: 2
Reputation: 1110
bottom line - use const.
more details:
I'm not a c++ expert, but this seems a more general design question.
If it's not a must, and you think there's a very low/non-existent probability that the enum will grow to have more then one value, then use a regular const. even if you are wrong and at some point in the future there will be more values, making an enum the right choice - a simple refactoring and you change you const to enum.
Upvotes: -3