views:

475

answers:

5
+6  Q: 

8 bit enum, in C

I have to store instuctions, commands that I will be receiving via serial. The commands will be 8 bits long.

I'd like to use Enumerations to deal with them in my code. Only a enumeration corresponds to a ... on this platform I think a 16 bit integer.

I need to preserve transparancy between command name, and its value. So as to avoid having to translate an 8-bit number received in serial into any type.

BTW the platform is AVR ATmega169V microcontroller, on the Butterfly demo board. It may be being underclocked to preserve power (I'm opposed to this, I believe the ATmega169V uses no power, not next to a router. But that's getting offtopic.) So I need to keep things fast, and I don't have any luxuries like file I/O. Or operating systems.

So any suggestions as to what type I should be using to store 8-bit commands?
There has got to be something better than a massive header of #defines.

+3  A: 

I don't see why an enum wouldn't work. Comparisons to, and assignments from, an enum should all work fine with the default widening. Just be careful that your 8 bit values are signed correctly (I would think you would want unsigned extension).

You will get 16-bit comparisons this way, I hope that won't be a performance problem (it shouldn't be, especially if your processor is 16-bit as it sounds like it is).

Keith Randall
thing is, my serial input is most deinititly 8bit.I'm not sure if the ALU works on 16 or 8 bit. Most of thje assembly cannands only work on 8bit bytes, there are less than 5 that works on 2 byte words (ADDW, MOVW is all i can bring to mind).Only
Oxinabox
I checked, it's 8bit
Oxinabox
@oxinabox - I'm still not sure that that has to do with the size of the enum type. Store the 8bit values in a `uint8_t` variable (or something else that corresponds to a byte). You'll still be able to compare and assign the enum values to them (as long as the enums are less than 256). Just don't use the enum type as the variable type if the exact size is important to the application
Michael Burr
A: 

Microsoft's C compiler allows you to do something like this, but it's an extension (it's standard in C++0x):

enum Foo : unsigned char {
    blah = 0,
    blargh = 1
};

Since you tagged GCC, I'm not entirely sure if the same thing is possible, but GCC might have an extension in gnu99 mode or something for it. Give it a whirl.

Jed Smith
Umm, I tagged AVR-GCC.I'll have to lookup what extentions it supports
Oxinabox
I'm interested in what you find. This was a gut shot.
Jed Smith
And it seems MS is the only one which supports such syntax.
Roman Nikitchenko
+14  A: 

gcc's -fshort-enums might be useful:

Allocate to an "enum" type only as many bytes as it needs for the declared range of possible values. Specifically, the "enum" type will be equivalent to the smallest integer type which has enough room.

In fact, here's a page with a lot of relevant information. I hope you come across many GCC switches you never knew existed. ;)

Michael Foukarakis
I'll add that to my collection of useful gcc switches that I never knew existed.
Tim Post
Ha, I realised today that if i compliler via AVR studio 4 IDE, then it's on by default
Oxinabox
A: 

I'd recommend to stay on enum in any case for the following reasons:

  • This solution allows you to map command values directly to what your serial protocol expects.
  • If you really use 16-bit architecture there is not so big number of advantages to move to 8 bits type. Think about aspects other then 1 memory byte saved.
  • At some compilers I used actual enum size used minimal number of bits (enums that could be fit in byte used only byte, then 16 bit then 32).

First you should not care about real type width. Only if you really need effective way of storage you should use compiler flags such as -fshort-enums on GNU compiler but I don't recommend them unless you really need them.

As last option you can define 'enum' as presentation data for the commands and use conversion to byte with 2 simple operations to store / restore command value to/from memory (and encapsulate this in one place). What about this? These are very simple operations so you can even inline them (but this allows you to really use only 1 byte for storage and from other side to perform operations using most usable enum defined as you like.

Roman Nikitchenko
8 bit architecture. i checked the hardware dos, it's 8bit
Oxinabox
+1  A: 

You are trying to solve a problem that does not exist.

Your question is tagged C. In C language enum types in value context are fully compatible with integral types and behave just like other integral types. When used in expressions, they are subjected to exactly the same integral promotions as other integral types. Once you take that into account, you should realize that if you want to store values described by enumeration constants in a 8-bit integral type, all you have to do is to choose a suitable generic 8-bit integral type (say int8_t) and use it instead of enum type. You'll lose absolutely nothing by storing your enum constant values in an object of type int8_t (as opposed to an object explicitly declared with enum type).

The issue you describe would exist in C++, where enum types are separated much farther from other integral types. In C++ using an integral type in place of enum type for the purpose of saving memory is more difficult (although possible). But not in C, where it requires no additional effort whatsoever.

AndreyT
thread necromacy much? this thread was declared answered almost 4 months ago. and it was answered correctly.
Oxinabox
@oxinabox.ucc.asn.au: The thread poped up on the first page. I don't know why. Oh, I see. *You* edited it (replacing "comment" with "commend", BTW :) and now you accuse *me* of therad necromancy?
AndreyT
BTW, it was not bad he responded to as it is the best answer of all. In C enum is nothing more than a declaration of constants, the storage of the values is independent of the enum. My 2 cents.
tristopia