В некоторых ситуациях объединения могут помочь вам создать эффективный код. Однако, если вы записываете представителя объединения и читаете обратно другого представителя объединения, поведение зависит от размеров представителей и может быть зависимым от реализации. Для реализации необходимо определить следующее:
Заполнение - Заполнение может быть вставлено в конец объединения.
Выравнивание (Alignment) - представители структур в объединении могут иметь различные выравнивания.
Endianness - хранится ли самый значительный байт слова по самому низкому или высокому адресу памяти.
Порядок битов - биты в байтах могут иметь как разную нумерацию, так и распределение по битовым полям.
Когда вы используете объединения в своем коде, из-за этих проблем, Polyspace® верификация может потерять точность.
Если вы пишете представителя объединения и читаете назад другого представителя объединения, Polyspace считает, что последний представитель может иметь любое значение, которое позволяет его тип. В этом коде представитель b
от X
написано, но a
считывается. Polyspace считает, что a
может иметь любое int
значение и обе ветви if-else
оператор достижим.
typedef union _u { int a; char b[4]; } my_union; void main() { my_union X; X.b[0] = 1; X.b[1] = 1; X.b[2] = 1; X.b[1] = 1; if (X.a == 0x1111) { } else { } }
Чтобы избежать использования объединений в вашем коде, проверяйте на нарушения MISRA C:2012 Rule 19.2
.
Примечание
Если вы инициализируете объединение с помощью статического инициализатора, следуйте ANSI® Стандарт C, Polyspace считает, что представитель объединения, появляющийся первым в списке объявлений, инициализируется.