Проблема заключается в том, что как скорость и процент молчаливо способствует целочисленные поощрений к типу «ИНТ». Таким образом, умножение выполняется на подписанном типе.
МИСРА код совместит либо переписать код, как
uint16_t basic_units = (uint16_t)rate * (uint16_t)percentage;
или же как следует МИСР, сразу же приведение результата выражения к его «базовому типу»:
uint16_t basic_units = (uint8_t)(rate * percentage);
EDIT : Далее следует разъяснение.
ИСО 9899: 1999 6.3.1.1 2
Если INT может представлять все значения исходного типа, значение преобразуется в Int; в противном случае он преобразуется в беззнаковый int. Они называются целым числом рекламных акций.
информативный текст из MISRA-C:
MISRA-C: 2004 6.10.3 Опасные преобразования типов:
/-/
- Изменение знаковости в арифметике Операции: Интегральное продвижение часто приводит к двум неподписанным операндам, дающим результат типа (подписанный) int. Например, добавление двух 16-разрядных неподписанных операндов приведет к подписанному 32-битовому результату, если int - это 32 бита, но беззнаковый 16-разрядный результат, если int - 16 бит.
Я на самом деле не знает, выше ли вторая линия шахты будет удовлетворять MISRA или нет, на второй мысли я могу спутал MISRA 10,1 с 10,5, где последний обеспечивает соблюдение немедленного приведения к базовому типу, но только в случае определенных поразрядных операторов.
Я тестировал обе линии с помощью анализа статического кода LDRA, и он не жаловался (но дает некоторые неправильные, несвязанные предупреждения), но тогда LDRA также очень плохо работает на MISRA-C.
Во всяком случае, проблема в исходном вопросе является то, что скорость и процент оба неявно преобразуются в целых поощрениях к типу Int, который подписывается, поскольку Int могут представлять все значения в uint8_t. Таким образом, это становится
uint16_t basic units = (int)rate * (int)percentage.
Для предотвращения этого вы должны явно указывать тип. Подумав, я поеду с первой строкой моих двух.
Вы хотите перевести на: uint16_t' во 2 строчке, да? – pmg
Почему продвижение двух неподписанных типов 'uint8_t' приводит к подписанному типу' int', а не к более большому неподписанному типу 'unsigned int' или более просто' uint16_t'? – Ioan
@pmg Я думаю, что я фактически перепутал правила 10.1 и 10.5 MISRA. Если бы это были ~ или << операторы, которые я бы заставил MISRA привести к типу в «базовый тип». Я редактировал свой пост, чтобы прояснить ситуацию. – Lundin