Соответствие MISRA C для арифметического сложения

Учитывая переменные a, b и c:

uint32_t a;
uint16_t b, c;

Согласно стандарту MISRA-C 2012, выражение a+b+c соответствует, тогда как b+c+a не соответствует.

Почему?


person ram surada    schedule 05.08.2015    source источник
comment
Честно говоря, этот вопрос слишком загадочен...   -  person Synxis    schedule 05.08.2015
comment
извините, вопрос должен заключаться в том, что U32a + u16b + u16c соответствует требованиям MISRA-C, а U16a + u16b + u32c не соответствует требованиям.   -  person ram surada    schedule 05.08.2015
comment
@ramsurada Что такое MISRA C? Что такое u32a, u16c, u16c? (Я знаю ответы, но, держу пари, большинству участников этого сайта они не очевидны.)   -  person Tavian Barnes    schedule 05.08.2015
comment
@Tavian MISRA-C – это стандартная структура кодирования, позволяющая разработчикам предоставить доказательства того, что они осведомлены и/или избегают языковых конструкций C, которые приводят к поведению, которое не гарантируется стандартом(ами) (т. е. неопределенные, неуказанный, и поведение, зависящее от реализации). Это также относится к четко определенным конструкциям языка C, которые (за многие годы практики) показали (или явный намек) на непреднамеренное поведение. См. Misra-c.com   -  person Veriloud    schedule 06.08.2015
comment
Подскажите номер правила.   -  person n. 1.8e9-where's-my-share m.    schedule 06.08.2015


Ответы (2)


С u16a+u16b+u32c u16a+u16b представляет собой unsigned (думаю, 16-битное) сложение с потенциальным переполнением, которое теряется до последующего добавления к u32c.

u32a+u16b+u16c добавляет u32a+u16b, а затем использует этот 32-битный результат при добавлении 16c, предотвращая эту потерю.

Пример

0x8000 + 0x8000 + 0x10000 
(0x8000 + 0x8000) + 0x10000 
0 + 0x10000 
0x10000 

vs.

0x10000 + 0x8000 + 0x8000
(0x10000 + 0x8000) + 0x8000
0x18000 + 0x8000
0x20000 
person chux - Reinstate Monica    schedule 05.08.2015

Поскольку C позволяет автоматически выполнять присваивания между различными арифметическими типами, использование этих неявных преобразований может привести к непреднамеренным результатам с потенциальной потерей значения, знака или точности. MISRA_C:2012 применяет строгую типизацию с помощью своей модели «основного типа», чтобы предупреждать, когда это может произойти, — известные как правила 10.x.

В этом случае существует вероятность потери переполнения с u16a+u16b+u32c

В частности, это нарушение MISRA C:2012 Rule-10.7: «Если составное выражение используется как один операнд оператора, в котором выполняются обычные арифметические преобразования, то другой операнд не должен иметь более широкий существенный тип».

Распространенной ошибкой является предположение, что на оценку влияет более широкий тип. Тип выражения фактически определяется типом его операндов после любого целочисленного расширения. Вы можете исправить это, приведя к более широкому типу или переставив операнды в начале выражения, как показано в первом примере: u32a+u16b+u16c

Примечание: это не означает, что все операнды в выражении относятся к одному и тому же существенному типу. Выражение u32a + u16b + u16c соответствует требованиям, так как оба сложения теоретически будут выполняться в типе uint32_t.

person Veriloud    schedule 06.08.2015
comment
Большое спасибо Chux, Rici и Veriloud. Теперь я понял. - person ram surada; 08.08.2015