gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > Sizes of enums and type consistency

#132141 - simonjhall - Sat Jun 23, 2007 9:13 pm

Is there any way to force the type and size of an enumation in C, via some compiler option?
One thing I noticed in Quake was that the code (compiled with VS) expected four-byte enums (even if they've only got enough entries to warrant a single byte).
Also with this MPEG stuff there seems to be a variation between building with ARM and THUMB!

Ok, so the code has an enum in it,
Code:
typedef enum {
    STATE_BUFFER = 0,
    STATE_SEQUENCE = 1,
    STATE_SEQUENCE_REPEATED = 2,
    STATE_GOP = 3,
    STATE_PICTURE = 4,
    STATE_SLICE_1ST = 5,
    STATE_PICTURE_2ND = 6,
    STATE_SLICE = 7,
    STATE_END = 8,
    STATE_INVALID = 9,
    STATE_INVALID_END = 10
} mpeg2_state_t;

but at one point (so far) in the code it's taken -1 and casted it to mpeg2_state_t, and returned it as type mpeg2_state_t. Then the code tests to see if the value is negative and does something etc etc.
On the PC with Visual Studio I get -1 'correctly' returned.
On the DS with gcc -marm I get -1.
On the DS with gcc -mthumb I get 255.
To handle the thumb version I added a dummy entry into the enumeration with value -1 and then I get a correct -1 back out (rather than 255).

So same compiler, difference results. Is there any way to get consistent results? I know you shouldn't make assumptions about the size of enumerated types and also their values in undefined cases, but there's gotta be something that can be done so as not to catch out other people porting code!

Peace.
_________________
Big thanks to everyone who donated for Quake2

#132164 - kusma - Sun Jun 24, 2007 12:35 am

a common fix to that "problem" (I'd say the problem is really the code if it treats enums as something else than what it is, but yeah) is something like this:
Code:

enum some_enum {
   SOME_VALUE,
   SOME_OTHER_VALUE,
   FORCE_DWORD = 0xFFFFFFFF
};

#132185 - simonjhall - Sun Jun 24, 2007 12:12 pm

Yeah, that's what I thought!
Seems a bit nasty though and you might not realise that you'd have this problem until a few hours into a fun debug session!

I still can't understand why there'd be a difference between ARM and THUMB mode though - isn't the front end the same, it's just the code generation that's different?
_________________
Big thanks to everyone who donated for Quake2

#132186 - tepples - Sun Jun 24, 2007 12:39 pm

You can use compile-time assertions to check whether sizeof(your enum type) is correct.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#132333 - PeterM - Mon Jun 25, 2007 11:24 pm

Somewhat related, I seem to recall that VC++ allows you to forward declare enums (it assumes the size) and pass them around, but GCC doesn't (it needs to know the size).
_________________
http://aaiiee.wordpress.com/

#132345 - wintermute - Tue Jun 26, 2007 3:01 am

simonjhall wrote:

I still can't understand why there'd be a difference between ARM and THUMB mode though - isn't the front end the same, it's just the code generation that's different?


I'd have thought so and some test code I just wrote outputs (mpeg2_state_t)-1 as 255 in both arm and thumb mode. Admittedly I'm currently using what will be devkitARM r21 and perhaps you've encountered a bug that was fixed in gcc 4.1.2.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog