patterncMinor
Converting a region code (short string up to 4 characters) to a 32-bit integer
Viewed 0 times
bitshortcharacterscodeconvertingstringregioninteger
Problem
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
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
Alternatively use union to ensure better alignment:
Is alignment a valid concern? If so which alternative seems less ugly to you?
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?
Solution
Even if the
Note that I used
One thing: since these are 4 byte integers, you can use an endianness-independent way of doing things by using
char array is not aligned, your ((uint32_t )buf) will be correct: the compiler will ensure the necessary operations are performed.Note that I used
unit32_t: the C standard does not guarantee the size of an int.One thing: since these are 4 byte integers, you can use an endianness-independent way of doing things by using
htonl()/ntohl().Context
StackExchange Code Review Q#26739, answer score: 2
Revisions (0)
No revisions yet.