Question

I am working with embedded device, with 32K of memory, writing in plain C using IAR EWARM v6.30.

To make code more readable I would like to define some enum types, for example, something like

{RIGHT_BUTTON, CENTER_BUTTON, LEFT_BUTTON}

instead of using 0, 1, 2 values, but I am afraid it will take additional memory that is already scarce.

So I have 2 questions: 1) Can I force enum to be of short or byte type intead of int? 2) What is an exact memory imprint of defining enum type?

Was it helpful?

Solution

In fully compliant ISO C the size and type of an enum constant is that of signed int. Some embedded systems compilers deliberately do not comply with that as an optimisation or extension.

In ISO C++ "The underlying type of an enumeration is an integral type that can represent all the enumerator values defined in the enumeration.", so a compiler is free to use the smallest possible type, and most do, but are not obliged to do so.

In your case (IAR EWARM), the manual clearly states:

enter image description here

No option required, in fact you'd need to use --enum_is_int to force compliant behaviour. Other compilers may behave differently or have different extensions, pragmas or options to control this. Such things will normally be defined in the documentation.

OTHER TIPS

If you really need to keep the data size down to a char then you can always use a set of #define constant values to represent the enum states and only ever use these values in the your assignments and tests.

For a conforming compiler, an enumerated constant is always of type int (equivalently, signed int). But such constants aren't typically stored in memory, so their type probably won't have much effect on memory requirements.

A declared object of the enumerated type is of the enumerated type itself, which is compatible with char or with some signed or unsigned integer type. The choice of type is implementation-defined (i.e., the compiler gets to choose, but it must document how it makes the choice); the only requirement is that the type has to be capable of storing the values of all the constants.

It's admittedly odd that the constants are of type int rather than the enumerated type, but that's how the language is defined (the reasons are historical, and C++ has different rules).

For example, given:

enum foo { x, y, z };
enum foo obj;
obj = z;

the expression z is of type int and has the value 2 (just like the decimal constant 2), but the object obj is of type enum foo and may be as small as one byte, depending on the compiler. The assignment obj = z; involves an implicit conversion from int to enum foo (that conversion may or may not require additional code).

Some compilers may provide some non-standard way to specify the type to be chosen for an enumerated type. Some may even violate the standard in some way. Consult your compiler's documentation, print out the value of sizeof (enum foo), and, if necessary, examine the generated code.

It's likely that your compiler will make reasonable decisions within the constraints imposed by the language. For a compiler targeted at memory-poor embedded systems, it's particularly likely that the compiler will either choose a small type, or will let you specify one. Consult your compiler's documentation.

As Ian's answer suggests, if you want to control memory usage yourself, you can use char or unsigned char objects. You can still use an enum definition to define the constants, though. For example:

enum { x, y, z }; // No tag, so you can't declare objects of this type
typedef unsigned char foo; // an enum_foo object is guaranteed to be 1 byte
foo obj = z;

Reference: section 6.7.2.2 of the C standard. The link is to a 1.7-megabyte PDF of a recent draft of the 2011 ISO C standard; this particular section hasn't changed significantly since 1989.

An ANSI C compiler will always represent an enum as an int to represent variables of type enum.

http://en.wikipedia.org/wiki/Enumerated_type#C_and_syntactically_similar_languages

One option to use ints in your program would be to use them to define values, but cast to char when actually used

char value = (char)Buttons.RIGHT_BUTTON;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top