Amardeep
Amardeep

Reputation: 89

MISRA C Rule 15.5 Multiple exit in a function due to multiple usage of a define which is having return

I am trying to get rid of violation of rule 15.5 from my code.

Sample code:

#define RETURN_VAL(num) {return (2 * num);} 

static int32_t
func(int32_t n1, int32_t n2, int32_t n3)
{  
    if (n1 == 1) {                
        RETURN_VAL(1);
    }
    if (n2 == 2) {
        RETURN_VAL(2);                  
    }
    if (n3 == 3) {
        RETURN_VAL(3);             
    }

    return 0;
}

Since the MACRO(having return value) is using in multiple places, result in violation of Rule 15.5.

Is there anyway to fix this keeping as MACRO itself.

Upvotes: 1

Views: 7481

Answers (3)

Andrew
Andrew

Reputation: 2312

Rule 15.5 is advisory... just disapply it.

It's a Rule that exists to satisfy a requirement of IEC 61508 and ISO 26262 that dates from the days of assembly language.

High level languages will implement the early return as a "Goto Exit", maintaining the principle of one-entry/one-exit.

Upvotes: 0

Lundin
Lundin

Reputation: 213892

Regarding using multiple return statements in a function, it is perfectly fine if it leads to more readable code. Rule 15.5 is a questionable one, with a questionable rationale, see this.

That being said, the main problem here is the use of pointless function-like macros, which violates Directive 4.9 of MISRA-C. Overall, the function interface is strange, do you really need to use 3 named parameters? A better alternative:

static int32_t func(int32_t n[N])
{  
    for(int32_t i=0; i<N; i++)
    {
      if(n[i] == i+1)
      {
        return 2 * (i+1);
      }
    }
    return 0;
}

If you must preserve the icky API for some reason, then use a wrapper:

inline static int32_t func_wrapper (int32_t n1, int32_t n2, int32_t n3)
{
  return func( (int32_t[3]){n1, n2, n3} );
}

Upvotes: 3

Rishikesh Raje
Rishikesh Raje

Reputation: 8614

You can modify the code above to remove multiple returns using an integer retval

If you absolutely have to use a Macro before returning use one as shown below. Do not hide the return statement with a macro. It will not affect any MISRA analysis.

#define  RET(num) (2 * num)

static int32_t
func(int32_t n1, int32_t n2, int32_t n3)
{  
    int32_t retval = 0;
    if (n1 == 1) {                
        retval = RET(1);
    }
    else if (n2 == 2) {
        retval = RET(2);
    }
    else if (n3 == 3) {
        retval = RET(3);             
    }

    return retval;
}

Upvotes: 2

Related Questions