I am looking for an elegant alternative of the following code where wordXX contains always 16 bits:

uint64_t wordHi = 0xaa; // I would like u_int16_t over u_int64_t here
uint64_t wordMi = 0xbb; // because it represents the real data better
uint64_t wordLo = 0xcc;

uint64_t largeword = (wordHi << 32) + (wordMi << 16) + (wordLo << 0);

To me this (very simplified) code looks a bit dirty, because reader gets confused about the real size of the wordXX data.

I could store wordHi to largeword and then shift largeword and add wordMi and so on, but this would make the code worse and probably needs more CPU cycles.

Edit: changed u_int64_t to uint64_t in the example as suggested in the comments.

  • \$\begingroup\$ Please either post your real code or remove the "very simplified" disclaimer. \$\endgroup\$ Commented Mar 2, 2016 at 22:34
  • 2
    \$\begingroup\$ The performance concerns of a handful of bit operations are almost certainly going to be negligible. Even if this is inside the tightest loop you can imagine, I highly doubt that you would see much of a performance hit over that, and I strongly doubt you could find a more readable and efficient method of doing that. \$\endgroup\$ Commented Mar 2, 2016 at 22:34
  • \$\begingroup\$ @200_success with simplified I want to express that the 16-bit integers are of course not constant values. So largeword = 0xaabbcc; would not help me a lot. \$\endgroup\$ Commented Mar 2, 2016 at 22:41
  • \$\begingroup\$ @Dannnno to me it looks strange to convert all 16-bit values to 64-bit, just to be able to shift them later. OK I could store wordMi to 32-bit and wordLo to 16-bit. But that makes it not much better... \$\endgroup\$ Commented Mar 2, 2016 at 22:45
  • \$\begingroup\$ Why are you using u_int64_t instead of the standard uint64_t? Why aren't you using u_int16_t for the words? \$\endgroup\$ Commented Mar 2, 2016 at 22:46

2 Answers 2


Using uint16_t not a problem?

Your comment says you want to use uint16_t, so why don't you do that? It would make the code look like this:

uint16_t wordHi = 0xaa;
uint16_t wordMi = 0xbb;
uint16_t wordLo = 0xcc;

uint64_t largeword = ((uint64_t) wordHi << 32) + ((uint64_t) wordMi << 16) + wordLo;

Use a struct and a union to do what you want. Note that this implementation is verbose and can be combined into a single declaration. Also depending on your system architecture, you may need to pack the struct or declare the members in a different order.

typedef struct
  uint16_t Low;
  uint16_t Mid;
  uint16_t Hi;
  uint16_t Spare;
} Word64_t;

typedef union
  uint64_t Int64Val;
  Word64_t WordVal;
} Splitter_t;

Splitter_t splitter;
splitter.WordVal.Low = 0xaa;
splitter.WordVal.Mid = 0xbb;
splitter.WordVal.Hi = 0xcc;

printf("%x", splitter.Int64Val);  //should print 0xaabbcc
  • \$\begingroup\$ I think you would run into endianness issues with this solution. \$\endgroup\$
    – JS1
    Commented Mar 3, 2016 at 1:39
  • \$\begingroup\$ @JS1 That may be. It depends on the architecture, as I said. I do this all the time in embdeded. \$\endgroup\$
    – Zack
    Commented Mar 3, 2016 at 3:15
  • \$\begingroup\$ If you can check the endianness of your architecture in a #define, you could define the order of elements in the struct differently based on the value of the #define. \$\endgroup\$ Commented Mar 3, 2016 at 3:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.