Subject: Re: emuns on ARM: What should we do?
To: None <>
From: Todd Vierling <>
List: port-arm
Date: 01/21/2002 10:50:03
On Mon, 21 Jan 2002, Richard Earnshaw wrote:

: > struct foo {
: >     enum bar a;
: >     int b;
: >     enum baz b;
: > };

: For someone who does care about space savings, the above structure would
: be written as
: struct foo {
:     enum bar a;
:     enum baz c;
:     int b;
: };
: Which would then save upto 33% of memory.

However, the person is still assuming something about the physical sizes of
those enums, based on the values of the enum in a C source file at "this
particular compile time".  Read on.

: > This will adversely impact:
: >
: > * big-endian ARM (because ABI incompatibilities are masked on little-endian
: >   systems by virtue of the fact that the LSB is first in a 4-byte int)
: No, it just means that the bug is likely to show itself earlier (one could
: regard that as a good thing).
: > * any uninitialized memory for a struct that is initialized by element (the
: >   extra bytes may get random data in code that assumes a shorter enum size)
: so... anyone comparing structures with memcmp or equivalent should be shot!

I said nothing about comparing structures.  The problem lies in creating a
structure from, say, stack-space, initializing an enum, and then passing it
to code that thinks the enum is larger.  Whoops, there's random data in byte

(This is the way that the same problem described for big-endian ARM
manifests on little-endian systems.)

: > If space is such an issue, then -fshort-enums is not your answer.  That's
: > simply asking the compiler to make assumptions about your code that don't
: > help *general code* on a system that requires type alignment.
: >
: > If code *really* needs a space gain, it should be using bit-sized types and
: > not relying on a compiler hack.  If code is designed to save space, it
: > should be designed to know *exactly* how large its data is.
: Bit-sized enums are not portable.

I didn't say bit-sized enums.  I said bit-sized types.  INTEGERS.  As in,
rearranging the above example:

struct foo {
    uint32_t b;
    uint8_t a;
    uint8_t c;

This contains no assumptions about the sizes of an enum type, and can store
enum types just as well as "enum" itself.  Here, you explicitly state how
large of a value is allowed to go into that struct; you have no masked ABI
incompatibilities; and you don't as the compiler to hack around your own
sloppiness.  In fact, you even gain the ability to make the struct
machine-independent by making sure there are no compiler-generated alignment

*No* other design (including, but not limited to, -fshort-enums) can be
justified under the argument of "it saves data space"; that's simply bogus.
If you don't define the sizes of your types ahead of time, you should *not*
be relying on the compiler to work around your own laziness.

: Anyone who really wanted to ensure portability of an interface that might
: change over time would simply add a place-holder enum that forced the type.

Again, you're asking established, working code to add something that has not
been required for >30 years, just to make it work the same as it has for
that same time.

-- Todd Vierling <>  *  Wasabi & NetBSD:  Run with it.
-- CDs, Integration, Embedding, Support --