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

now*_*wox 2 c qualifiers misra void-pointers

我写了这个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;
}
Run Code Online (Sandbox Code Playgroud)

我使用IAR作为编译器和C-STAT进行静态分析.

Lun*_*din 6

您无法memcpy使用标准格式进行编写并且完全符合MISRA标准.你似乎注意到了,MISRA不允许restrict.但也有规则11.5.

规则11.5关于从指针到虚拟到指针到类型的强制转换在实践中过于繁琐.这是一个咨询规则,所以我会跳过它.你不需要提出偏差.

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

const int_least8_t* source = (const int_least8_t*) src;
Run Code Online (Sandbox Code Playgroud)

补充说明:

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

  • @Persixty MISRA-C 鼓励使用 `stdint.h`,如果您不使用 stdint 类型,则需要一个充分的理由。这不是一个很好的理由 - 如果您的系统不支持 `uint8_t` 但有 16 位字符,那么您的 DSP 就会出现故障。您应该使用汇编程序而不是 C 语言进行编码。普通的 C 程序绝对不需要为奇怪的、奇异的、过时的 DSP 提供可移植性。这样做的人只是在浪费大家的时间。提供对现实世界主流计算机体系结构的可移植性就足够了。 (2认同)