MISRA-C 2012 Правило 10.8 Запрос - PullRequest
0 голосов
/ 16 мая 2018

Я получаю сообщение MISRA-C 2012 Rule 10.5, ниже приведен пример кода:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

typedef long long       sint64; 
typedef unsigned long long  uint64;
typedef unsigned long   uint32;

#define ntohll(x) ( ( (uint64)(ntohl( ((x << 32) >> 32) )) << 32) | ntohl( ((uint32)(x >> 32)) ) )

void main()
{
 sint64 pul_total;
 sint64 a;
 pul_total = ntohll(a); /* Rule 10.8 Violation*/    
}

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ для решения проблемы, которую я попытался выполнить ниже:

#define ntohll(x) ( ( (uint64)(ntohl( ((x << 32) >>(uint32)32) )) << (uint32)32) | ntohl( ((uint32)(x >>(uint32) 32)) ) )

но все же это разочарование

Однако, если я сделаю это, как показано ниже, нарушение будет удалено:

  #define ntohll(x) ( ( (uint64)(ntohl( ((x << 32) >> 32) )) << 32) | ntohl( ((uint32)((uint32)x >> 32)) ) )

но, согласно моему пониманию, преобразование подписанной переменной в unsigned может быть не очень хорошей идеей в случаесменная операция.

Нужна помощь для того же ...

1 Ответ

0 голосов
/ 16 мая 2018

Весь этот код определенно не совместим с MISRA-C.

  • Прежде всего, есть некоторые менее важные придирки. Директива 4.9 гласит, что функциональных макросов следует избегать полностью. И правило 7.2 гласит, что вы должны использовать суффикс u для всех целочисленных констант.

  • Наиболее серьезным здесь является нарушение 10.1, которое гласит: «Сдвиговые и побитовые операции должны выполняться только с операндами по существу беззнакового типа ».

    Вы оставили сдвиг подписанного операнда - если этот операнд отрицательный, ваш код вызывает неопределенное поведение и у вас серьезная ошибка. Затем вы также сдвигаете вправо подписанный операнд, который вызывает поведение, определяемое реализацией, если операнд отрицательный. Это не просто некоторые ложные срабатывания, а реальные ошибки, которые вы должны исправить. Самый простой способ - привести x к uint64_t перед любым смещением.

  • Я не вижу нарушения 10.5, которое приведёт к неприемлемому типу. Разрешается разыгрывать с подписи на без знака.

  • Однако, как указывает ваш комментарий, есть нарушение 10.8 - правило не разрешает приводить результат «составного выражения» к другой категории типов, в вашем случае от sint64_t до uint64_t или uint32_t. Эту проблему тоже можно решить, приведя к uint64_t , прежде чем сделает что-то еще.

    (довольно странное) обоснование для 10.8 состоит в том, что некоторые начинающие предположительно думают, что приведение типа, например, (uint32_t)(u16a + u16b);, означает, что операция + выполняется на uint32_t, что неверно.

Теперь реальный вопрос в том, чего на самом деле пытается добиться весь этот сдвиг; это мне не понятно. Макрос довольно грязный. Если намерение состояло в том, чтобы очистить некоторые биты переменной, это должно быть сделано с битовой маскировкой (поразрядно &) И если причины неизвестных знаковых переменных должны использоваться и знак должен сохраняться, битовая маска может просто пропустить бит знака.

Лучший способ исправить этот код - полностью переписать этот макрос. Как он есть, он никогда не пройдет MISRA-C, что хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...