3 ms·
Thanks for the explanation! That makes sense. I knew from reading K&R that, in converting a char to an int without sign extension, casting to unsigned char firs
by trealira 2y ago
Thanks for the explanation! That makes sense. I knew from reading K&R that, in converting a char to an int without sign extension, casting to unsigned char first is just as good as masking by 0xFF after, and I guess I was just not sufficiently familiar with the type promotion rules of C.
This now causes a runtime error:
#include <stdio.h>
#include <stdint.h>
char b[4] = {0x82,0x03,0x04,0x80};
#define UC(x) ((unsigned char) (x))
#define READ32BE(p) (uint32_t)UC(p[3]) | UC(p[2]) << 8 | UC(p[1]) << 16 | UC(p[0]) << 24
int main(void) {
printf("%08x\n", READ32BE(b));
}
----
endian.c:8:22: runtime error: left shift of 130 by 24 places cannot be represented in type 'int'
82030480
But this works:
#include <stdio.h>
#include <stdint.h>
char b[4] = {0x82,0x03,0x04,0x80};
#define CH_to_U32(x) ((uint32_t) (unsigned char) (x))
#define READ32BE(p) (CH_to_U32(p[3]) \
| CH_to_U32(p[2]) << 8 \
| CH_to_U32(p[1]) << 16 \
| CH_to_U32(p[0]) << 24)
int main(void) {
printf("%08x\n", READ32BE(b));
}
----
82030480