Reputation: 1357
I have a code
#include <iostream>
#include <string.h>
using namespace std;
int main() {
// your code goes here
uint8_t x[4] = {55, 11, 0, 20};
uint16_t y;
memcpy(&y, &x[0], 2);
std::cout<<y<<std::endl;
return 0;
}
(hex of 55 - 37, hex of 11 - B) in which I expect y to contain "37B"(i.e., - 891 in decimal). But, Y actually contains "B37"(i.e., 2871 in decimal). How to maintain the order with memcpy without endian swap operation.
Upvotes: 0
Views: 7716
Reputation: 223767
The reason you're getting B37
is because you're on a little-endian machine.
The call to memcpy
is doing what you would expect. The value 0x37
is copied to the first byte of y
, while 0x0B
is copied to the second byte of y
. And because you're on a little-endian architecture, the first byte of y
is the least significant. So it contains the value 0xB37
.
If you want x[0]
to be the high byte and x[1]
to be the low byte of y
, you need to do it in a way that doesn't depend on endianness:
y = x[1]; // y = 0x0B
y |= x[0] << 8; // y = 0x0B | 0x3700 = 0x370B
This will give y
a value of 0x370B
. However this is still not the 0x37B
value you expect.
If that's what you want, you need to recognize that 0x37B
has a value of 0x03
for the high byte and 0x7B
for the low byte.
So you would either need to define x
as follows:
// note the use of hex constants to make the values more clear
uint8_t x[4] = {0x7b, 0x3, 0x0, 0x14};
Or you would need to perform some additional bit shifting to get the values you need:
y = x[1]; // y = 0x0B
y |= x[0] << 4; // y = 0x0B | 0x370 = 0x37B
Upvotes: 1
Reputation:
memcpy
copies memory. And it does maintain the order of the bytes of memory. You can't make memcpy
do something else.
Your problem is that you don't want to copy memory; you want to do some particular arithmetic operation (e.g. concatenate two 8-bit values to get a 16-bit value).
Exactly how integer types are laid out in memory is unspecified behavior. On your CPU, your memcpy
hack does not perform the arithmetic operation you want. Thus, to do what you want, have to do something other than (or in addition to) memcpy
.
I advise doing the arithmetic operation with arithmetic operations: you'll get code you can be sure works on everything*, and your program will most likely perform similarly (or even better) than the hack anyways, especially with compiler optimizations turned on.
*: everything that has the relevant types, of course
Upvotes: 3