Безопасное присвоение значений битовому полю в C - PullRequest
0 голосов
/ 21 сентября 2018

Предположим, у меня есть

typedef struct {
    unsigned short bar   :    1;
} foo_bf;

typedef union {
  unsigned short val;
  foo_bf bf;
} foo_t;

Как правильно назначить значение этому битовому полю из типа, например, uint16_t?

uint16_t myValue = 1;
foo_t foo;
foo.bf.bar = myValue 

Запуск PC-Lint, это превращается в MISRAошибка: Выражение, присвоенное более узкому или другому важному типу.

Я попытался ограничить количество используемых бит без успеха.

foo.bf.bar = (myValue 0x1U)

Есть ли шансчтобы сделать его совместимым с MISRA, если мне нужно использовать значение uint16_t в качестве источника?

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Приложение D.4 MISRA C: 2012 полезно озаглавлено «Основные типы битовых полей»

  • Для битового поля, которое реализовано с по существу логическим типом , это по существу логическое
  • Для битового поля, которое реализовано с типом со знаком , это Тип со знаком самого низкого ранга который может представлять битовое поле
  • Для битового поля, которое реализовано с беззнаковым типом , это Беззнаковый тип самого низкого ранга , которыйв состоянии представить битовое поле

Тип без знака без наименьшего ранга одноразрядного целого числа без знака будет uint8_t (он же без знака)) - при условии, что инструмент не интерпретирует один бит как логическое значение ...

Помимо наблюдения, что PC-Lint выглядит как неправильная диагностика, обходной путь, позволяющий избежать любой возможностиСомнение бы бросить:

foo.bf.bar = (uint8_t)myValue

Как в стороне MISRA C: 2012 Правило 6.1 дает руководство по использованию типов, отличных от int со знаком / без знака, для битовых полей ...

0 голосов
/ 21 сентября 2018

Модель основных типов MISRA-C на самом деле не применима к битовым полям.Термины, более узкие и широкие, относятся к размеру в байтах (см. 8.10.2).Таким образом, не очевидно, должен ли статический анализатор предупреждать здесь или нет, поскольку правила для основного типа не обращаются к битовым полям.
РЕДАКТИРОВАТЬ: Я был не прав здесь, см.ответ Андрея.В Приложении D.4 рассказывается, как преобразовать тип битового поля в соответствующую категорию существенного типа.

Однако использование битовых полей в приложении MISRA-C - плохая идея.Битовые поля очень плохо определены стандартом и поэтому недетерминированы и ненадежны.Кроме того, MISRA-C 6.1 требует, чтобы вы документировали, как ваш компилятор поддерживает битовые поля с uint16_t, поскольку это не один из стандартных целочисленных типов, разрешенных для битовых полей.

Но реальный прерыватель сделкиВот Директива 1.1, которая требует, чтобы все поведение, определяемое реализацией, было задокументировано и понято.Для реализации MISRA-C я однажды попытался задокументировать все аспекты реализации битовых полей.Вскоре я обнаружил, что пишу целое эссе, потому что с ними так много проблем. См. для вершины айсберга.

Обходной путь для того, чтобы не писать такую ​​«книгу поведения битовых полей», - безоговорочно запретить использование битовых полей полностью в вашем стандарте кодирования.В любом случае, они на 100% лишние.Вместо этого используйте побитовые операторы.

...