$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Emile Cormier (emilecormier_at_[hidden])
Date: 2006-03-07 16:13:38
Martin Bonner wrote:
> ----Original Message----
> From: Emile Cormier
>
>> The bitfield mechanism relies on this assumption: Unions of
>> non-polymorphic, non-derived objects, having the exact same underlying
>> data member type, will have the same size as this underlying data
>> member type. I'm no language lawyer, so please let me know if this is
>> a safe and portable assumption.
>
> I'm not quite sure what you mean, but given:
> struct a { unsigned char ch; };
> struct b { unsigned char ch; };
> union u { a theA; b theB };
> then you are not guaranteed that sizeof(u) == sizeof(unsigned char).
>
> On word addressed machines (which /are/ still being built), it is almost
> certain that the minimum size for a struct is a complete word. This is
> because the C and C++ standards effectively promise that pointers to
> structs are all of the same size (the size of a pointer-to-struct does
> not depend on the contents of the struct). It is desirable that a
> pointer-to-struct be the smaller, cheaper-to-dereference pointer to word
> (rather than the larger more-expensive-to-dereference pointer to char),
> so the smallest struct has to occupy a whole word.
>
> HOWEVER, if your structures and unions are using unsigned char, why not
> just use "unsigned char *" instead? If you are using unsigned short (or
> longer types), then you are almost certain to be safe. It is not
> guaranteed by the standard; a compiler /can/ pad all structures to 256
> bits if it wants to, but in practise compilers don't.
>
>
I've just run some tests on an ARM platform (arm-elf-gcc), and sizeof(u)
from Martin's example above always returns 4 regardless of whether char,
short, or long are used. If I use the -fpack-struct option, then
sizeof(u) becomes 1/2/4 for char/short/long respectively.
On gcc x86, i get sizeof(u) = 1/2/4 for char/short/long without
-fpack-struct.
Martin is on to something about using pointers. The pointer already
"knows" how to access char/short/long integers. The disadvantage of
using pointers is their storage space and the indirection to the actual
data. For example, a system with 50 8-bit registers would require
50*sizeof(char*) bytes to store the pointers.
I'd prefer that the bitfield manipulate the data directly, so that, for
example:
union hardware_reg
{
bitfield<uint16_t, 4, 8> bf1;
};
hardware_reg a;
a.bf = val;
is equivalent to:
uint16_t a;
a = (a & 0xfff0) | ( (val & 0x000f) << 4 );
rather than:
uint16_t a;
uint16_t* p = &a;
*p = (*p & 0xfff0) | ( (val & 0x000f) << 4 );
I've got another way of doing bitfields up my sleeve that is not as
syntactically pretty as C++ bitfields, but may be much more portable.
I'll let you know when I've uploaded "version 2" to the Boost vault.