【发布时间】:2021-12-14 01:44:58
【问题描述】:
Misra 标准要求函数的单点退出,但我有以下“转换”代码
typedef enum { CASE_A, CASE_B, CASE_C } my_enum_t;
int my_conv_funct(my_enum_t value)
{
switch(value)
{
case CASE_A:
return 0;
case CASE_B:
return 1;
case CASE_C:
return 2;
default:
break;
}
log_error("ERROR!!!!!");
assert(1==0);
}
这有效吗? 我需要将其转换为单个返回函数吗? 处理默认情况的最佳方式是什么?
这在理论上创建了一个无法访问的代码(错误是警告如果在枚举中添加一个值而不是添加相应的情况)
这是一个嵌入式系统,顺便说一句,这些断言会产生问题?
谢谢, 尼克
编辑:
如果没有错误,则不应调用默认情况(例如,程序员在枚举中添加另一个值并且不添加相应的情况
另一种选择是完全删除默认设置,但这违反了另一个 misra 规则
typedef enum { CASE_A, CASE_B, CASE_C } my_enum_t;
int my_conv_funct(my_enum_t value)
{
switch(value)
{
case CASE_A:
return 0;
case CASE_B:
return 1;
case CASE_C:
return 2;
}
//should never reach this line
assert(1==0);
}
如果我编译并且没有指定枚举中的所有案例(我认为),这将生成一个警告
【问题讨论】:
-
你创建了一个“int retVal;”最后返回。
-
如果您在嵌入式系统上,您希望断言语句会发生什么?也许您希望 MCU 重新启动?那么你就可以这样做了。
-
代码格式一般不正确。因为
assert是一个宏,可能会被预处理掉,从而导致函数的代码路径不返回有效值。最好定义一个错误返回码并将其用于默认路径(除了断言之外)。 -
这是很棒的代码。但请记住:发明 misra 是为了限制/惩罚不合标准的程序员。
-
如果您在嵌入式系统上,您需要有处理断言的代码。您可能想要做的事情是将相关调试信息存储在不会在重新启动时重新初始化的内存部分中,然后强制重新启动。一些有用的指导在这里barrgroup.com/Embedded-Systems/How-To/…。没有这种特殊代码,你的
assert会做什么?
标签: c switch-statement default assert misra