[bitfield] Initial bitfield proposal available in the vault

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[bitfield] Initial bitfield proposal available in the vault

Emile Cormier
You can download the code at the Boost vault:

http://boost-consulting.com/vault/index.php?&direction=0&order=&directory=bitfield

test.cpp contains a regression test that you can try on your compiler.
Please let me know if it works, as I've only tested this on MinGW GCC
3.4.

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.

Let me know if things aren't sufficiently self-explanatory, or if things
can be improved.
--
  Emile Cormier
  [hidden email]

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [bitfield] Initial bitfield proposal available in the vault

Martin Bonner
----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.


--
Martin Bonner
[hidden email]
Pi Technology, Milton Hall, Ely Road, Milton, Cambridge, CB4 6WZ,
ENGLAND Tel: +44 (0)1223 203894

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [bitfield] Initial bitfield proposal available in thevault

Andy Little

"Martin Bonner" <[hidden email]> wrote in message
news:[hidden email]...

> ----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).

Though in practise you can use:

BOOST_STATIC_ASSERT(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.

I dont see why the size of a pointer to a struct affects the size of a struct
which in the case of an empty struct is often 1 byte?

regards
Andy Little




_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [bitfield] Initial bitfield proposal available in the vault

Emile Cormier
In reply to this post by Martin Bonner
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.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [bitfield] Initial bitfield proposal available in thevault

Andy Little

"Emile Cormier"  wrote

> Martin is on to something about using pointers. The pointer already
> "knows" how to access char/short/long integers.

Surely any pointer must be capable of being converted to a void* which means
void* has to know about the extra bits? How does that work?
I would have thought it would be possible to reinterpret_cast (or somehow
convert) the struct to the inbuilt type in these situations isnt it thus fooling
the compiler into storing that type?
The problem I see is that there seems to be two types of pointers here which
doesnt seem to be standard C++ behaviour?

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.

Whereas you've exceeded your 36 bit word so it would seem better to chop it into
words if necessary in this case?

I wonder if this doesnt all come down to platform-dependent padding or
alignment?

> I'd prefer that the bitfield manipulate the data directly, so that, for
> example:

[...]

I think that is more traditional use
...  especially in case of memory mapped ports etc. I would have thought that
being forced to use a pointer (with all the problems pointers entail) would be
very of-putting.

IIRC Theres some outline information about ports and tentative useage in n1666
"Technical report on C++ Performance" Chapter 8 "Hardware Addressing Interface"
which may also be relevant.


regards
Andy Little




_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost