Есть такая структура:
typedef struct {
uint32_t flags : 12;
uint32_t addr : 20; // Верхние 20 бит адреса
} some_type_t;
void set_addr(some_type_t* sv, uint32_t addr)
{
sv->addr = addr >> 12;
}
В итоге GCC выдаёт такую ошибку:
error: conversion from 'uint32_t' {aka 'long unsigned int'} to 'unsigned int:20' may change value [-Werror=conversion]
31 | sv->addr = addr >> 12;
| ^~~~~~~~~~
Решилось всё таким вариантом:
uint32_t addr_shifted = addr >> 12;
sv->addr = addr_shifted & 0xFFFFFu;
0xFFFFF это маска для 20 нижних бит.
Она вроде как говорит компилятору, что верхние 12 бит нас не интересуют.
Но что более забавно, такой код не работает:
sv->addr = (addr >> 12) & 0xFFFFFu;
Почему?