1

This is just to meet the so-called Misra C 2012 specification rule 15.5. I have to make only one return statement in my function, but I want to do the parameter check of the function. When the parameter check fails, it can end directly. With this function, there is no need to execute the following code. The code that does not meet the specification is as follows:

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;
}

How to improve it?

Cocion
  • 13
  • 3
  • 2
    Yes having one return statement is nice but honestly sometimes you'll have code where there are so many conditions and upon a single failure it doesn't make sense to continue the rest of the function execution so you just return instantly. – Irelia May 06 '21 at 12:18

3 Answers3

1

You'll need to store the return code as a separate variable and put the code following the if block into an 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;
}
dbush
  • 205,898
  • 23
  • 218
  • 273
  • Doing so will make the code less readable, and what if there are multiple error returns? – Cocion May 07 '21 at 01:43
  • @Cocion In that case you'll have multiple nested `if` blocks. Yes it's less readable but if you're required to comply to MIRSA without deviation this is what you're stuck with. – dbush May 07 '21 at 01:47
  • If you have a clipboard monitor telling you to do *to comply to MIRSA without deviation* please tell them to get in touch with me... they need re-educating! – Andrew May 07 '21 at 18:41
1

Generally when writing MISRA-C compliant code you'd start your function with something like

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

Then you change it to an error code if something goes wrong and return it at the end.

Notably, your code would benefit from enum named error codes instead of magic numbers 0, -1 etc. When we have an enum error code type we can make every single function in our API return that same type, then document which return values that are possible per function. Very user-friendly and makes it way more pleasant to write error handles in the calling application.

Now regarding the specific MISRA-C rule, I've been giving this particular one some pretty sour critique over the years, see this. And rightly so if you follow the chain of sources they give as rationale for the rule... So the sound solution might just be to create a permanent deviation against the rule in your coding standard. As noted in comments to that link, the rule was demoted from Required to Advisory in MISRA-C:2012 so you don't even need a formal deviation.

Personally I go with this rule:

Functions should only have one single return statement unless multiple return statements make the code more readable.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • The rationale for the Rule is, indeed, clouded in the mists of time... as an advisory, to help maintain structured code, it has its place. But blind adherence should be discouraged. – Andrew May 06 '21 at 17:57
  • Thank you for your optimized solution. I very much agree with your error code solution and agree with your principle of using function export. Thanks again. – Cocion May 07 '21 at 01:10
1

MISRA C Rule 15.5 is an Advisory rule.

This means that you do not require a "formal" deviation to justify violations, although you should still document it. The justification of "Code Quality - readability" is appropriate (see MISRA Compliance)

Alternatively, you could use a forward GOTO, although this too breaches an Advisory rule.

So what I'm saying is that, while MISRA makes some recommendations, there are appropriate mechanisms to follow if you feel you need to violate one of those Rules - and you can get appropriate sign-off, and as long as you are fully aware of the consequences..

Blind adherence to a Rule can result in poorer-quality code than controlled violation!

[See profile for affiliation]

Andrew
  • 2,046
  • 1
  • 24
  • 37
  • Thank you very much for your valuable comments. I really want to use GOTO statements like the Linux kernel source code. I personally think that as long as the direction of GOTO jumps is the exit position of the function, there will be no logical confusion. This is actually in line with the 15.2 rule of Misra c 2012, but my leader still refuses to use GOTO. – Cocion May 07 '21 at 01:34