Unsigned to signed cast is implementation defined (though in practice it has the expected 2's complement semantics on essentially every relevant platform). However, the only reason we used one in the first place was to take advantage of arithmetic right shift broadcasting the sign bit to the full length of a 32-bit integer. This requires right shift of negative numbers to be defined as arithmetic – in C it is instead UB. The remaining unsigned-to-unsigned casts would have been all defined, but it is easier to keep the codebase UB-free by just banning all direct casts. Since we do want to convert between 32-bit and 64-bit integers, introduce meri_casts.h as a way to make the intent clear and warn on any extra unintended implicit casts at the callsite.
5 lines
276 B
C
5 lines
276 B
C
// Casts that could be safely done implicitly, but we want to be explicit
|
|
static inline uint64_t meri_u32_u64(uint32_t val) { return val; }
|
|
|
|
// Casts that lose information, but where we want that
|
|
static inline uint32_t meri_u64_low_u32(uint64_t val) { return (uint32_t)val; }
|