Reputation: 15109
I have this POC
#include <stdio.h>
#include <stdint.h>
int main(void) {
unsigned char *c = "This is ";
uint64_t i;
int j;
i = c[7] | (c[6] << 8) | (c[5] << 16) | (c[4] << 24) | (c[3] << 32) | (c[2] << 40) | (c[1] << 48) | (c[0] << 56);
printf("c value: '%s'\n", c);
printf("Hex:");
for (j = 0; j < 8; j++) {
printf(" %2x", c[j]);
}
printf("\n");
printf("Is i equal to c? %d\n",
memcmp((unsigned char *)&i, "\x54\x68\x69\x73\x20\x69\x73\x20", 8)
);
return 0;
}
I have an unsigned char *
(please note the white space at the end!) and an uint64_t
which I'm filling in with the data from the unsigned char *
.
Then I memcmp
both vars and I'd expect to get 0
, but I get -1
. Why is that?
I'm thinking it has something to do with how c
is promoted in the bitwise operations, but I can't find exactly what is going wrong.
Upvotes: 0
Views: 857
Reputation: 28654
If you take this code:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main(void) {
unsigned char *c = "This is ";
uint64_t i;
int j;
i = (uint64_t ) c[7] | ((uint64_t )c[6] << 8) | ((uint64_t )c[5] << 16) | ((uint64_t )c[4] << 24) | ((uint64_t )c[3] << 32) | ((uint64_t )c[2] << 40) | ((uint64_t )c[1] << 48) | ((uint64_t )c[0] << 56);
printf("c value: '%s'\n", c);
printf("Hex:");
for (j = 0; j < 8; j++) {
printf(" %2x", c[j]);
}
printf("\n");
printf("Printing i contents as they appear in memory \n");
unsigned char *k=(unsigned char*)&i;
for(int j = 0;j<8 ;j++)
printf("%2x ",(unsigned) k[j]);
printf("\n");
printf("Is i is equal to c? %d\n",
memcmp(&i, "\x54\x68\x69\x73\x20\x69\x73\x20", 8)
);
return 0;
}
The output on my machine which is little endian is:
c value: 'This is '
Hex: 54 68 69 73 20 69 73 20
Printing i contents as they appear in memory
20 73 69 20 73 69 68 54
You can see the bytes are reversed when stored in memory. This should give you clue that if your PC is little endian, i
's least significant byte which is ' ' will be stored at the beginning in the memory address.
Upvotes: 3