2015-10-05 11 views
2

Я пишу код в соответствии с правилом MISRA. Я получаю ошибку Мишра для выражения нижеОшибка MISRA 10.1 Неявное преобразование комплексного целого

check_Val = (~ (0x000Fu < < Src_Data)); // где Src_Data - uint8, а check_Val - uint32.

Я проанализировал ошибку

нарушающую Мишра 2004 Обязательное правило 10.1, неявное преобразование сложного целого выражения

С check_Val является uint32, то Lf должен поместиться на ней. Тогда почему это дает ошибку.

+0

Какой инструмент дает вам этот выход? – amdixon

+0

Возможный дубликат [Bitshift and integer promotion?] (Http://stackoverflow.com/questions/3482262/bitshift-and-integer-promotion) –

+1

@TomTanner Как это может быть дубликат, если он вообще не упоминает MISRA ? – Lundin

ответ

3

Правило 10.1 касается неявного продвижения целых чисел с использованием концепции «базового типа» MISRA: 2004, то есть предполагаемого типа выражения. Это было странное понятие, которое привело к многочисленным излишним броскам, это было зафиксировано в MISRA: 2012.

Подходящим типом выражения является целочисленный литерал 0x000Fu. Для целых литералов он указывал, что базовый тип - это наименьший возможный тип, который способен представлять объект (см. P40-41). Таким образом, базовый тип 0x000Fu будет uint8_t, так как он может поместиться в байте, и он имеет неподписанный тип.

Несмотря на то, что в отношении языка C и компилятора этот целочисленный литерал имеет тип unsigned int, и никаких рекламных акций не будет. MISRA: 2004 все равно.

Это означает, что перед операцией вы должны отдать операнд uint32_t (обход правила 10.1) или отдать его на uint8_t после операции (передать 10.1, а также 10.5 относительно сдвигов). Я предлагаю вам отправить его на uint32_t, чтобы избавиться от проблемы. Поэтому

Фиксированный код должен быть

check_Val = ~((uint32_t)0x000Fu << Src_Data); 

Кроме того, поскольку оба операнда оператора сдвига являются целым числом способствует, оператор правой получает неявно повышен до int, а также. Это продвижение никогда не может нанести вред, и я не уверен, что это даже нарушение MISRA, но я полагаю, что это может вызвать предупреждения. В этом случае, вы также должны отбрасывать правый операнд:

check_Val = ~((uint32_t)0x000Fu << (uint32_t)Src_Data); 

Я бы рекомендовал использовать Мишра: 2012, если это возможно, где были выяснены эти правила и понятие «базовый тип» было замененный на тот, который не приводит к множеству бессмысленных бросков.

+0

'UINT32_C (0xF)'? – EOF

+0

@EOF Извините, что? – Lundin

+0

Это способ указать константу соответствующего размера и значения. Хотя это, по-видимому, создает значение типа 'uint_least32_t', а не' uint32_t', поэтому я не уверен, что MISRA примет его. – EOF