MikroC — ошибка в стандартных заголовочных файлах

Попытка подключить к проекту модуль NanoPB не увенчалась успехом. Этот модуль предназначен для упаковывания (сериализации) данных, и поэтому он часто использует всяческие встроенные макросы работы с полями структур и определения длин переменных — и как оказалось,  один такой стандартный, встроенный макрос offsetof содержит ошибку, из-за которой его применение вызывает «const expression expected».

Его реализация выглядит так:

#define offsetof(s, m) (size_t)&(((s *)0)-›m)

Однако, классическая версия ничем не отличается:

#define offsetof(s, m) (size_t)&(((s *)0)-›m)

На самом деле, ошибка вовсе не в нем, а в компиляторе. По стандарту, операция взятия члена структуры приоритетнее, чем операция определения длины поля — то есть, запись sizeof Str->elem вернет длину поля elem. В MikroC же эти приоритеты перепутаны — и он пытается взять поле elem у длины.

Значит, ошибка в компиляторе? Да, но стандарт MISRA C говорит нам — «пишите код так, чтобы он не зависел от ошибок в компиляторе». Этой проблемы могло бы не быть, поставь они скобки, чтобы явно указать очередность выполнения.

Ссылка на основную публикацию