The union method is at best determined by the implementation (in practice, it will work quite reliably, but the si format depends on the nature of the platform).
The problem with the bitwise way, as you suspect, is related to negative numbers. A negative number is represented by a chain of leading 1. So, -5, for example,
1111 1011
If you discard this value to int or even unsigned int , it becomes
1111 1111 1111 … 1111 1011
and all these 1 will drown the left-shifted data when applying OR.
To solve the problem, move char to unsigned char and then to int (to prevent overflow or even overflow) before the transfer:
short int stitch(char c1, char c2) { return ( (int) (unsigned char) c1 << 8) | (unsigned char) c2; }
or, if you can change the types of arguments, and you can include <cstdint> ,
uint16_t stitch( uint8_t c1, uint8_t c2) { return ( (int) c1 << 8 ) | c2; }
source share