There is a function that converts region code strings (1 to 4 characters and null terminator) to 32 bit integers codes to be used in maps as keys or values.
Blindly casting char* to int* is bad as it can be less than 4 bytes including null terminator.
Currently the code is like this
uint32_t region_code_key(const char* region_code) {
unsigned char buf[4] = "\0";
strncpy(buf, region_code, 4);
return *((int*)buf);
}
I believe that buf may be not well aligned causing problems on some platforms. Is it a valid concern? The endianity is not a concern as such numbers are used only on local machines, only as keys.
It's a very simple function but If alignment concern is valid I see two ways to rewrite it. Here we just convert it byte by byte
uint32_t region_code_key(const char* region_code) {
unsigned char* region_code_iter;
unsigned char* region_code_end = region_code+4;
uint32_t code_as_int = 0;
for (region_code_iter = region_code; region_code_iter!=region_code_end && (*region_code_iter); ++region_code_iter) {
code_as_int = (code_as_int<<8) | (*region_code_iter);
}
return code_as_int;
}
Alternatively use union to ensure better alignment:
uint32_t region_code_key(const char* region_code) {
union {
char[sizeof(uint32_t)] as_string;
uint32_t as_int;
} region = {0, 0, 0, 0};
strncpy(region.as_string, region_code, sizeof (region_code));
return region.as_int;
}
Is alignment a valid concern? If so which alternative seems less ugly to you?