Портативный пример кода:
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#define CHARS_TO_U32(c1, c2, c3, c4) (((uint32_t)(uint8_t)(c1) | \
(uint32_t)(uint8_t)(c2) << 8 | (uint32_t)(uint8_t)(c3) << 16 | \
(uint32_t)(uint8_t)(c4) << 24))
static inline uint32_t string_to_u32(const char *string)
{
assert(strlen(string) >= 4);
return CHARS_TO_U32(string[0], string[1], string[2], string[3]);
}
#define VERSION_2_3_7 CHARS_TO_U32('0', '2', '3', '7')
#define VERSION_2_4_1 CHARS_TO_U32('0', '2', '4', '1')
int main(int argc, char *argv[])
{
assert(argc == 2);
switch(string_to_u32(argv[1]))
{
case VERSION_2_3_7:
case VERSION_2_4_1:
puts("supported version");
return 0;
default:
puts("unsupported version");
return 1;
}
}
Код предполагает только существование целочисленных типов uint8_t
и uint32_t
и не зависит от ширины и подписи типа char
, а также от порядкового номера. Он свободен от коллизий, если кодировка символов использует только значения в диапазоне uint8_t
.