Сообщение компилятора не велико - оно объединяет несколько ошибок в одно сообщение.Ваш вызов макроса создает текст:
((xyz)->y= (val));
Проблема в том, что xyz
является структурой, и поэтому вы получаете доступ к членам, используя xyz.y
, а не xyz->y
.Вы можете вызвать:
set_val(&xyz, val);
, и это будет работать нормально;Вы передаете указатель, а затем разыменовываете, используя обозначение указателя.Или вы можете переписать макрос следующим образом:
#define set_val(xyz, val) ((xyz).y = (val))
Обратите внимание, что имена аргументов макроса xyz
и val
только совпадают с передаваемыми аргументами.Я мог бы написать макрос как:
#define set_val(s, value) ((s).y = (value))
или
#define set_val(p, value) ((p)->y = (value))
(в зависимости от того, какую версию вы хотите сохранить), и он будет работать так же.Однако повторное использование одних и тех же имен может привести к путанице.
Возможно, стоит также отметить, что подобные макросы не всегда являются хорошей идеей, поскольку могут привести к путанице.Вы могли бы добиться большего успеха с помощью встроенной функции:
static inline void set_val(v1 *p, u32_t val) { p->y = val; }
Теперь, по крайней мере, вы получите лучшее сообщение об ошибке, если вы назвали его неправильно.Конечно, функция должна иметь указатель на структуру - семантика функции по-прежнему применяется даже к встроенным функциям.До сих пор неясно, является ли функция полезной, но безопасность типов, которую накладывает сигнатура функции, очень помогает.