0

I have following structs:

struct ID
{
   UINT id;         // range from 0 to 10 000 000
   UINT residentNb; // range same as for id (above).
};

struct FullID
{
   ID myID;
   ID systemID;
};

Now, UINT id in above struct ID have specified range in my system. This range is always from min 0 to max 10 000 000. I would like to transform struct FullID to one number, UINT64 for example, and be able to encode/decode data from it - myID and systemID (like in above struct). Is it possible, and what is the best way to do it? Of course 10 000 000 limit can be rounded to some higher value if this is necessary for proper conversions.

Example

UINT64 encodedID;

(...)

FullID fullID = Decode(encodedID);

(...)

encodedID = Encode(fullID);
DannyX
  • 395
  • 1
  • 5
  • 11

1 Answers1

1

I suggest using a union to avoid strict aliasing optimization bugs (google for strict aliasing if you do not know what it is).

And then, just use bitmasks and bitshifts to encode/decode. Stay away from bitfields, they are not easy to work with if you want portable code.

Erik Alapää
  • 2,585
  • 1
  • 14
  • 25
  • Reading about it right now... Optimization is very important for me. Can you give an example (implementation of Encode/Decode functions). I want to be sure I dont get any strange bugs... – DannyX Dec 23 '15 at 08:15
  • How can you use unions to avoid strict aliasing bugs? – eerorika Dec 23 '15 at 08:26
  • @user2079303 http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html – Erik Alapää Dec 23 '15 at 08:55
  • 1
    @DannyK: You have to figure it out for yourself, but one piece of advice is to use unsigned ints exclusively if you can, then you dont run into things like sign extension etc. when bitshifting. – Erik Alapää Dec 23 '15 at 08:57
  • @ErikAlapää might be worth mentioning that the article states that type punning through a union (except between `char*`) is strictly speaking undefined - although supported by major compilers. The article appears to be mostly about C99. Are the strict aliasing rules same as in C++? – eerorika Dec 23 '15 at 09:12
  • @user2079303 Yes, in spite of what some people say, C is essentially a true subset of C++. And at least with GNU gcc/g++, I have seen no differences in the aliasing rules between C and C++. Also, type-punning through a union is a common idiom that no sane compiler writer would break. – Erik Alapää Dec 23 '15 at 09:16