如何检查函数入口的形参,保证函数只有一个return语句?

问题描述

这只是为了满足所谓的 Misra C 2012 规范规则 15.5。我只需要在我的函数中做一个 return 语句,但我想做函数的参数检查。当参数检查失败时,可以直接结束。有了这个功能,就不需要执行下面的代码了。不符合规范的代码如下:

int32_t func(struct st *p,uint8_t num)
{
    if ((NULL == P) || (num > MAX_NUM)) {
        perror("print some error info");
        return -1;
    }

    // do something

    return 0;
}

如何改进?

解决方法

您需要将返回代码存储为单独的变量,并将 if 块后面的代码放入 else

int32_t func(struct st *p,uint8_t num)
{
    int32_t rval;
    if ((NULL == P) || (num > MAX_NUM)) {
        perror("print some error info");
        rval = -1;
    } else {
        // do something
        rval = 0;
    }

    return rval;
}
,

通常在编写符合 MISRA-C 的代码时,您会使用类似的东西来启动您的函数

int32_t result = OK; // whatever "OK" means in your context

然后,如果出现问题,您将其更改为错误代码并在最后返回。

值得注意的是,您的代码将受益于 enum 命名错误代码而不是幻数 0-1 等。当我们有 enum 错误代码类型时,我们可以我们 API 中的每个函数都返回相同的类型,然后记录每个函数可能返回的值。非常人性化,让在调用应用程序中编写错误句柄更加愉快。

现在关于特定的 MISRA-C 规则,这些年来我一直在对这个特定的规则进行一些非常酸溜溜的批评,see this。如果你遵循他们作为规则基本原理的来源链,那么正确的做法......所以合理的解决方案可能只是在你的编码标准中创建一个与规则的永久偏差。正如对该链接的评论所述,该规则在 MISRA-C:2012 中从“必需”降为“咨询”,因此您甚至不需要正式的偏差。

我个人遵循这个规则:

函数应该只有一个 return 语句除非多个 return 语句使代码更具可读性。

,

MISRA C 规则 15.5 是一项咨询规则。

这意味着您不需要“正式”偏差来证明违规行为的合理性,但您仍应记录下来。 “代码质量 - 可读性”的理由是恰当的(参见 MISRA 合规性)

或者,您可以使用前向 GOTO,尽管这也违反了咨询规则。

所以我要说的是,虽然 MISRA 提出了一些建议,但如果您觉得需要违反其中一项规则,则可以遵循适当的机制 - 并且您可以获得适当的签字,只要您完全了解后果..

盲目遵守规则会导致代码质量低于受控违规!

[查看隶属关系简介]