C - это не структура или объединение - PullRequest
0 голосов
/ 23 мая 2018

Следующий код дает мне ошибку компилятора: left side of '.' or '->' is not struct or union.

Пример кода:

struct x {
    u32_t y;
};
typedef struct x v1;

v1 xyz;
set_val(xyz, val); 

Здесь я получаю проблему, что xyz не является структурой или объединением,но это структура или нет?

#define set_val(xyz, val) ((xyz)->y=  (val))

Я искал это и нашел некоторых людей с такой же проблемой, но не понимаю, как ее исправить.

1 Ответ

0 голосов
/ 23 мая 2018

Сообщение компилятора не велико - оно объединяет несколько ошибок в одно сообщение.Ваш вызов макроса создает текст:

((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; }

Теперь, по крайней мере, вы получите лучшее сообщение об ошибке, если вы назвали его неправильно.Конечно, функция должна иметь указатель на структуру - семантика функции по-прежнему применяется даже к встроенным функциям.До сих пор неясно, является ли функция полезной, но безопасность типов, которую накладывает сигнатура функции, очень помогает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...