Поле size нужно, чтобы можно было использовать общие функции для
работы с буфером. Тем не менее твой вариант лучше всех предыдущих.
А для функций - надо определить базовую структуру, и работать с
буфером через нее: typedef struct { uint16_t const size; uint16_t ri; uint16_t wi; uint8_t buff_addr } base_t;
#define DECLARE_FIFO( X_name, Y_size) \
struct { \
uint16_t const size; \
uint16_t ri; \
uint16_t wi; \
uint8_t buf[Y_size]; \
} X_name = { Y_size, 0, 0 };
void Put(base_t *base_p, uint8_t byte) { (&base_p->buff_addr)[base_p->wi] = byte; if ( ++base_p->wi == base_p->size ) base_p->wi = 0; }