2015-08-05 5 views
1

Учитывая переменные a, b и c:МИСРА С для соответствия арифметического сложения

uint32_t a; 
uint16_t b, c; 

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

Почему?

+1

Честно говоря, этот вопрос слишком застенчив ... – Synxis

+0

жаль, что вопрос должен быть U32a + u16b + u16c совместимым с MISRA-C vs U16a + u16b + u32c, несовместимым. –

+0

@ramsurada Что такое "MISRA C"? Что такое "u32a", "u16c", "u16c"? (Я знаю ответы, но это не очевидно для большинства участников этого сайта, на который я бы поставил.) –

ответ

3

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

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

Пример

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

против

0x10000 + 0x8000 + 0x8000 
(0x10000 + 0x8000) + 0x8000 
0x18000 + 0x8000 
0x20000 
1

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

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

Конкретно это нарушение МИСРА С: 2012 Правило-10.7: «Если составное выражение используется в качестве одного операнда оператора, в котором обычный выполняется арифметическое преобразование, тогда другой операнд не должен иметь более широкий основной тип ».

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

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

+0

Большое спасибо Chux, rici и Veriloud. Теперь я понял. –