|
-
February 13th, 2007, 12:59 PM
#11
Re: How to get certain bits from a value?
 Originally Posted by Mitsukai
im pretty sure this works 99%
MinGW 3.4.5, Borland C++ 5.5.1, Digital Mars Compiler, OpenWatcom, SCC and Turbo C++ 1 are in the bad 1% part.
Code:
#include <stdio.h>
union Packet
{
unsigned long Value;
struct
{
unsigned long T: 1;
unsigned long P: 1;
unsigned long A: 1;
unsigned long Reserved: 4;
unsigned long E: 1;
unsigned long ScanCode: 8;
unsigned long RepeatCount: 16;
} x;
};
int main() {
Packet p;
p.Value=0xFFFFFFF0UL;
printf("%lu %lu",p.x.T,p.Value>>31);
return 0;
}
With all of them, output is "0 1"
 Originally Posted by Mitsukai
its most likely this struct does not contain padding bits.
unsigned long may have padding bits.
This structure may contain padding bits between bit fields as well. I hope you know that "unsigned long T: 1" doesn't imply AT ALL that T is stored in the same unsigned long word than P, A and others...
Actually, a 16 bits machine may very well store "unsigned long" bit fields that are shorter than 16 bits, in a 16 bits word, and add padding if necessary.
For example:
struct {
unsigned long T: 3;
unsigned long P: 15;
};
On a 16 bits platform, this structure might be stored with padding... T and P being stored in two separate 16 bits words.
Similarly, sizeof(struct {unsigned long T:1;}) might very well be 1 or 2 on a 16 bits machine!
In your structure, there seems to be no place for padding between bit-fields on sensible implementations on 8 bits byte machines.
since it only has one variable and it is an aggregate.
Wrong, it has 7 variables.
and what do you mean with bit order?
If two bit fields are stored in the same machine byte/word/multi-word... There are mainly two sensible organisations of this fields (and a lot of other organisations which aren't sensible):
Putting the first bit-field in the lower bits (i.e. less significant bits) of the byte/word/unit and the second bit-field in the higher bits.
Of course, new issues occur because of byte order of your "unsigned long Value"!
For example, assume a 16 bits little-endian compiler, which puts T, P, A and Reserved in a first 16 bits word, with a higher-bits-to-lower-bits order of bit-fields, and put E, ScanCode and RepeatCount in the next 16 bits word... Well, in that case, the bijection of bits of bitfields to bit of unsigned long will be weird.
And, of course little-endian byte order vs big-endian byte order is not universal... There exists more complex endianess... With big-endianess in 16 bits word and little-endianess in 32 bits word.
And, padding bits in unsigned long (which may be formed of several words) as well as padding bits in simple words, may complicate things.
Padding bits isn't a myth... There exists machines without real unsigned arithmetic, on which unsigned integers are simple signed integers with the sign bit always set to zero.
On common platforms, the main issue is due to placement of bit fields.
"inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
Club of lovers of the C++ typecasts cute syntax: Only recorded member.
Out of memory happens! Handle it properly!
Say no to g_new()!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|