Subject: Re: emuns on ARM: What should we do?
To: None <Richard.Earnshaw@arm.com>
From: Todd Vierling <tv@wasabisystems.com>
List: tech-toolchain
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
MSB+1....
(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
gaps!
*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 <tv@wasabisystems.com> * Wasabi & NetBSD: Run with it.
-- CDs, Integration, Embedding, Support -- http://www.wasabisystems.com/