分配给未使用的变量的最后一个值 [MISRA 2012 规则 2.2,必需]

Last value assigned to variable not used [MISRA 2012 Rule 2.2, required]

我在使用如下代码时收到此警告:

//Macro
#define FREEIF(p)            if (p) { free_mem((void*)p); (p) = 0; }

//free_mem function
int free_mem(void *mem_ptr)
{
    if (mem_ptr != NULL)
    {
        free(mem_ptr);
    }
    mem_ptr = NULL;
    return 0;
}


//Use of Macro in my .c file with above declaration and definition of macro.
....
....

{
 FREEIF(temp_ptr);
}

如果我在调用 MACRO 之前添加检查“temp_ptr”,例如 if (temp_ptr) {FREEIF(temp_ptr);},我不会收到此警告。

因为我已经在检查 MACRO 中的“temp_ptr”。我想知道为什么我会收到此警告。

有什么见解吗?

C 中的参数按值传递。这意味着作为参数传递的值被复制到函数内部可见的参数,并且修改函数中的参数对传递的原始值没有任何影响。

因此,行 mem_ptr = NULL; 是无意义的(至少假设没有未定义的行为(如越界读取或取消引用无效指针)似乎没有意义)因为 mem_ptr 是函数的局部赋值后根本不读取该值。

另一方面,(p) = 0; 可能不是没有意义,因为 p 没有在宏中声明,所以它会引用在宏之前声明的内容,并且可能在调用之后读取的宏。

关于错误,规则 2.2 是关于您的程序中没有任何“死代码”。

在函数中,mem_ptr = NULL;局部变量mem_ptr设置为null,而不是传递的那个。所以该代码行什么都不做。这是错误的原因,这是一个常见的初学者常见问题解答,请参阅 了解详细信息。

在类似函数的宏中,传递的指针会被 (p) = 0; 改变。但是,如果您在将指针设置为 null 后不使用它,它仍然被视为“死代码”,因为严格来说赋值是没有意义的(尽管是好的做法)。我们无法判断,因为您没有 post 调用代码,也没有实际的指针声明。

但这里还有一些更严重的大局问题:

  • 同时使用 MISRA-C 和动态内存分配是荒谬的。它们几乎是相互排斥的。嵌入式系统一般不使用动态分配,尤其是 metal/RTOS MCU 应用程序 simply doesn't make any sense.

    动态分配在mission-critical/safety-related软件中尤其被禁止。这不仅被 MISRA 禁止,而且被任何编码标准禁止。它也被 IEC 61508、ISO 26262、DO 178 等通用安全标准禁止

  • 除了安全性和 MISRA 之外,您的宏仍然是无意义的,因为空指针上的 free() 是一个明确定义的空操作。参见C17 7.22.3.3中free的定义:

    void free(void *ptr); /--/ If ptr is a null pointer, no action occurs.

    因此,宏的全部作用是混淆代码并使用额外的、无意义的分支减慢代码速度。

这里正确的解决方案是核对这个宏,然后退后一步,考虑一下你对这个项目做了什么。从要求开始。你为什么需要 MISRA-C,这个项目中有人知道他们在做什么,如果不知道 - 我们应该雇用谁来帮助这个项目。等等。对于使用 MISRA-C 的项目,您的团队至少需要一名 C 语言老手,否则该项目注定失败。