# What is this code doing?

## Recommended Posts

union
{
enum
{
MAX_BITS_INDEX = 16,
MAX_BITS_MAGIC = 16,

MAX_INDEX = ( 1 << MAX_BITS_INDEX ) - 1,
MAX_MAGIC = ( 1 << MAX_BITS_MAGIC ) - 1
};
struct
{
unsigned IndexNum : MAX_BITS_INDEX;
unsigned MagicNum : MAX_BITS_MAGIC;
};
ulong HandleID;
};

I have been using this code for a while because it worked and I thought I understood it. the union can only hold one type of data, does that mean if I input IndexNum and MagicNum, does this effect HandleID? and initially IndexNum and MagicNum are set to 16, correct? also: what does ( 1 << MAX_BITS_MAGIC ) - 1 do? I have never used << besides in console and fileoutput. Thanks

##### Share on other sites
i think that code is based on the resource managed demonstrated by (i think it was) scott bilas in game programming gems 1.
think of the enums as old-style static const variables. they are basically used here to limit the range of IndexNum and MagicNum to a specific bit size in order to make a handle instance 4 bytes in size (on x86) so it's efficient to pass a handle by value.

the union is simply there (look at the rest of the code from scott) to allow for easy zeroing out the handle, for instance. HandleId = 0 causes IndexNum and MagicNum to be zero aswell. HandleId itself is composed of the first few bits which are from IndexNum and then the next bits from MagicNum.

##### Share on other sites
Quote:
 Original post by biohazThe union can only hold one type of data, does that mean if I input IndexNum and MagicNum, does this effect HandleID?

Yes. They're two names for the same piece of memory. How they are related is implementation-dependant.
Quote:
 and initially IndexNum and MagicNum are set to 16, correct?

No, they are not initialized in the code snippet you posted. They are set to 16 bits in size, that's all. The colon in this case is the bitfield delimiter, not the initializer delimiter.
Quote:
 also: what does ( 1 << MAX_BITS_MAGIC ) - 1 do? I have never used << besides in console and fileoutput.

That chunkie of code is trying to deterimine the maximum integral value that could fit in a field containing MAX_BITS_MAGIC number of bits, assuming a twos-complement binary representation of integers. It's a compile-time computation so the compiler can optimize the actual computation away.

Please note that this tidbit of code is highly implementation dependendant and unlikely to work on, say, a different version of the same compiler let alone different compilers or different platforms. It doesn't, for example, take in to account the current struct packing (alighnment) rules.

##### Share on other sites
A union is a user defined type, which allows different "view"/"representation" of the contains data.

What i mean is, when you use this union, it is reserving a memory area of sizeof(ulong), since this is the longest datatype contains in the union. Then, you can access it using the "representation" you want.

union BitConverter{    struct    {       WORD highWord;       WORD lowWord;    }    DWORD longNumber;}

Using this BitConverter union you can easylly swap the high & low part (16bits) of an (32bits)dword. (I used to use something like this to convert from little-endian to big-endian ordering)

The >(Rightshifts the bits of an expression.).

ie: (00010010 <

##### Share on other sites
ahh... I think I understand unions now.

So would
union{    struct    {       WORD IndexNum;       WORD MagicNum;    }    DWORD HandleID;}

be more portable? now that I understand unions, it makes a lot more sense. Could you not also use shorts and long? though this would make it dependant again - it would still work, correct?

##### Share on other sites
Oups.. last post isnt rendering correctly...

Here it's the end...

The operator <

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

• ### Forum Statistics

• Total Topics
627719
• Total Posts
2978790

• 9
• 21
• 14
• 12
• 42