enums ain't no good


C

copx

C's enum type disappoints me a lot.

You cannot define which type of integer variable is used. This contradicts
C's low level spirit. "I want a number variable. I do not care about size or
execution speed." feels like typical ultra high level scripting language
design. The compiler could not optimize an enum if it wanted to, because you
cannot even specify whether memory requirements or speed are your primary
concern. Enums were meant to replace these endless lists of defines you find
all over older C source:
#define FOO 0
#define BAR 1
...
It is a technique commonly used to give index numbers meaningful names.
However, the variables which hold such numbers often do not need to be wider
than one byte and are used a lot. In one program I had many enum-type
variables as parts of my data structures and the amount of wasted RAM was
excessive when I used C enums, because the compiler (GCC) always used
(unsigned) ints, even if the entire range of valid values fitted into a
single byte. IMHO the definition of an enum should allow you to specify the
integer type. For example:

typedef int8_t enum {
FOO,
BAR
} MY_ENUM;

Not giving the programmer this type of control makes me feel like I am using
another language. What was the reasoning behind that decision? Did the guy
who designed the enum type also suggest to replace all of C's integer types
with "number"?

copx
 
Ad

Advertisements

L

Leo Havmøller

C's enum type disappoints me a lot.
You cannot define which type of integer variable is used.

Yes, a common annoyance. However, most compilers for embedded software has a
"treat enums like ints" option, that can be disabled, in order to achieve
auto-sizing enum's.

Leo Havmøller.
 
I

Ian Collins

copx wrote:

Ain't no good is a double negative....
C's enum type disappoints me a lot.
As they should, they are more than a little broken.

Not giving the programmer this type of control makes me feel like I am using
another language. What was the reasoning behind that decision? Did the guy
who designed the enum type also suggest to replace all of C's integer types
with "number"?
Where size matters (typically but not exclusively on embedded systems),
many compilers provide extensions to size enums.
 
B

Ben Pfaff

copx said:
C's enum type disappoints me a lot.

You cannot define which type of integer variable is used. This contradicts
C's low level spirit.

There's not much difference between, on one hand, defining an
enum type without a tag and then typedef'ing an integer type to
what name you like and, on the other hand, defining an enum type
with a tag and using the enum type directly. If the latter falls
short, you can just use the former.
 
C

copx

Leo Havmøller said:
Yes, a common annoyance. However, most compilers for embedded software has
a "treat enums like ints" option, that can be disabled, in order to
achieve auto-sizing enum's.

Yes, IIRC GCC has such an option, too. It chooses the narrowest type
possible. However, that is not the same as having full control over which
type is used, and as I have said, I think this should be doable at syntax
level.
 
C

copx

Ben Pfaff said:
There's not much difference between, on one hand, defining an
enum type without a tag and then typedef'ing an integer type to
what name you like and, on the other hand, defining an enum type
with a tag and using the enum type directly. If the latter falls
short, you can just use the former.

I have read about that technique in some embedded programming journal
recently. Yes, it works, but it is an ugly workaround for what is a language
design flaw IMO. Enums are supposed to define the type which is used to
store the enum values after all.
 
Ad

Advertisements

E

Eric Sosman

copx said:
C's enum type disappoints me a lot.
[...]
It is a technique commonly used to give index numbers meaningful names.
However, the variables which hold such numbers often do not need to be wider
than one byte and are used a lot. In one program I had many enum-type
variables as parts of my data structures and the amount of wasted RAM was
excessive when I used C enums, because the compiler (GCC) always used
(unsigned) ints, even if the entire range of valid values fitted into a
single byte.

You may have missed the fact that you can use the enum
declaration just to define the constants, and then store their
values in any type you are fond of:

enum { FOO, BAR, BAZ };
char foo = FOO;
unsigned long long bar = BAR;
long double baz = BAZ;
 
K

kar1107

C's enum type disappoints me a lot.

You cannot define which type of integer variable is used. This contradicts
C's low level spirit. "I want a number variable. I do not care about size or
execution speed." feels like typical ultra high level scripting language
design. The compiler could not optimize an enum if it wanted to, because you
cannot even specify whether memory requirements or speed are your primary
concern. Enums were meant to replace these endless lists of defines you find
all over older C source:
#define FOO 0
#define BAR 1
..
It is a technique commonly used to give index numbers meaningful names.
However, the variables which hold such numbers often do not need to be wider
than one byte and are used a lot. In one program I had many enum-type
variables as parts of my data structures and the amount of wasted RAM was
excessive when I used C enums, because the compiler (GCC) always used
(unsigned) ints, even if the entire range of valid values fitted into a
single byte.

Isn't that GCC's fault to waste memory and not a language flaw?

At least my understanding is that the actual enum type can be chosen
freely by the implementation as long it can fit all values [1]. So GCC
_could_ have used a byte (octet).

Karthik

[l]. From n869.txt 6.7.2.2 [#3]

[#4] Each enumerated type shall be compatible with an
integer type. The choice of type is
implementation-defined,99) but shall be capable
of
representing the values of all the members of the
enumeration. The enumerated type is incomplete until after
the } that terminates the list of enumerator declarations.



IMHO the definition of an enum should allow you to specify the
 
K

Keith Thompson

C's enum type disappoints me a lot.

You cannot define which type of integer variable is used. This contradicts
C's low level spirit. "I want a number variable. I do not care about size or
execution speed." feels like typical ultra high level scripting language
design. The compiler could not optimize an enum if it wanted to, because you
cannot even specify whether memory requirements or speed are your primary
concern. Enums were meant to replace these endless lists of defines you find
all over older C source:
#define FOO 0
#define BAR 1
..
It is a technique commonly used to give index numbers meaningful names.
However, the variables which hold such numbers often do not need to be wider
than one byte and are used a lot. In one program I had many enum-type
variables as parts of my data structures and the amount of wasted RAM was
excessive when I used C enums, because the compiler (GCC) always used
(unsigned) ints, even if the entire range of valid values fitted into a
single byte.

Isn't that GCC's fault to waste memory and not a language flaw?

At least my understanding is that the actual enum type can be chosen
freely by the implementation as long it can fit all values [1]. So GCC
_could_ have used a byte (octet).

Yes, it could, but why should it? On many systems, operations on
words (e.g., int or unsigned int) are faster than operations on bytes.
In some cases, data space saved by using bytes might be more than
offset by the increase in code size.
 
Ad

Advertisements

K

kar1107

Isn't that GCC's fault to waste memory and not a language flaw?
At least my understanding is that the actual enum type can be chosen
freely by the implementation as long it can fit all values [1]. So GCC
_could_ have used a byte (octet).

Yes, it could, but why should it? On many systems, operations on
words (e.g., int or unsigned int) are faster than operations on bytes.
In some cases, data space saved by using bytes might be more than
offset by the increase in code size.

OTOH, CPUs run way faster than the memory latency (100/1000 times?).
So any denser representation of data may not only result in less DRAM
usage, it will reduce the amount of data that must come into the CPU.
This can translate to a faster overall performance (less total time).

These days memories are getting bigger and cheaper and hence saving
DRAM usage may not be a bigger concern. Reducing the amount of data
that is shuttled back/n/forth from CPU to the memory will contribute
to a reduction in total time. Thus optimizing for space and time need
not be mutually exclusive.

In any case, I think this issue is orthogonal to the OP's original
concern that the language mandates enum types to be int; which it does
not (starting C99).

Karthik
 
Ad

Advertisements

E

Eric Sosman

[...]
In any case, I think this issue is orthogonal to the OP's original
concern that the language mandates enum types to be int; which it does
not (starting C99).

For clarity: The enumeration constants are all of type
`int', but the enum type itself is a distinct type of its
own, not an `int'. ANSI Classic 3.1.2.5p9 (before the ISO
re-numbering).
 

Top