分配给未使用的变量的最后一个值 [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 语言老手,否则该项目注定失败。
我在使用如下代码时收到此警告:
//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 语言老手,否则该项目注定失败。