Как написать функцию memcpy, полностью совместимую с MISRA:2012?

Я написал это memcpy функция, но мне все еще нужно отключить правила 11.5 и 11.8. Есть ли решение для полной совместимости с MISRA:2012?

#pragma cstat_suppress="MISRAC2012-Rule-21.6" // Uses of stdio.h were found.
#include <stdio.h>

#include <stdint.h>
#include <string.h>
#include <stdlib.h>

extern int main(void);

static int_least8_t _memcpy(void *dst, const void *src, const size_t length)
{
    #pragma cstat_disable="MISRAC2012-Rule-11.5" // A conversion from a pointer to void into a pointer to object was found.
    int_least8_t* destination = (int_least8_t*)dst;
    #pragma cstat_disable="MISRAC2012-Rule-11.8" // A cast that removes a const or volatile qualification was found.
    const int_least8_t* source = (int_least8_t*)src;
    #pragma cstat_restore="MISRAC2012-Rule-11.5","MISRAC2012-Rule-11.8"

    for (size_t i = 0; i < (length / sizeof(int_least8_t)); i++)
    {
        destination[i] = source[i];
    }
    return 0;
}

int main(void)
{
    int32_t src[32];
    int32_t dst[32];

    (void)memset(src, 0xff, sizeof(src));

    (void)_memcpy(dst, src, 128);

    for (size_t i = 0; i < (sizeof(src) / sizeof(src[0])); i++)
    {
        (void)printf("%d <=> %d\n", src[i], dst[i]);
    }

    return 0;
}

Я использую IAR в качестве компилятора и C-STAT для статического анализа.

1 ответ

Решение

Вы не можете написать memcpy со стандартным форматом и полностью совместимы с MISRA. Как вы, кажется, заметили, MISRA не позволяет restrict, Но есть и правило 11.5.

Правило 11.5, касающееся приведений от указателя к пустоте к указателю на тип, слишком громоздко, чтобы следовать на практике. Это консультативное правило, поэтому я просто пропущу его. Вам не нужно поднимать отклонение.

Однако правило 11.8, касающееся отбрасывания квалификаторов, является обоснованным (и обязательным). Нет никаких причин, почему вы должны сделать это в этом случае. В вашем коде есть ошибка, которая была предотвращена MISRA. Измените код на

const int_least8_t* source = (const int_least8_t*) src;

Дополнительные примечания:

  • Вам не нужно предоставлять предварительную декларацию main(),
  • stdio.h не допускается MISRA-C.
  • Избегайте объявления идентификаторов, начинающихся с подчеркивания, см. C11 7.1.3.
  • Там нет очевидной выгоды от использования int_least8_t Вот. Кроме того, подписанные типы являются проблематичными. я хотел бы использовать uint8_t вместо.
Другие вопросы по тегам