如何编写一个完全 MISRA:2012 兼容的 memcpy 函数?

How to write a memcpy function full MISRA:2012 compatible?

我写了这个 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 进行静态分析。

您无法使用标准格式编写 memcpy 并完全符合 MISRA 标准。您似乎已经注意到,MISRA 不允许 restrict。但还有规则 11.5.

规则 11.5 关于从 pointer-to-void 到 pointer-to-type 的转换在实践中太麻烦了。这是一个咨询规则,所以我会跳过它。你不需要提出偏差。

关于放弃限定词的规则 11.8 是一个合理的规则(并且是必需的)。在这种情况下,您没有理由这样做。您的代码中存在错误,已被 MISRA 阻止。将代码更改为

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

补充说明:

  • 您无需向 main() 提供函数声明。
  • MISRA-C 不允许
  • stdio.h
  • 避免声明以下划线开头的标识符,请参阅 C11 7.1.3。
  • 这里使用 int_least8_t 没有明显的好处。此外,签名类型也有问题。我会改用 uint8_t