MISRA Discussion Forums

Full Version: Goto to simulate Exceptions
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
There is a typical paradign where each routine returns a status, and on every call that status is checked. If the status is not \"OK\" then the function call stops, and returns to the calling function. There too, the functions checks the status and returns to it's caller and so on till as some point some function (the exception handler) checks the status and does something about it.

In this way when a error (exception) happens execution stops at that point and the stack is \"unwound\" till the point that it is handled.

In the \"new\" languages this is achieved using exceptions.

In C there are two typical ways of doing this - the \"return\" method and the \"if\" method;

Code:
status   foo(    )
{
      status st = OK;
  
     st = bar_aaa(   );
     if (st == OK) {
         st = bar_bbb(   ); }
     if (st == OK) {
         st = bar_ccc(   ); }

    return st;
}

Or this

Code:
status   foo(    )
{
      status st = OK;
  
     st = bar_aaa(   );
     if (st != OK) {
            return st;
     }
      
     st = bar_bbb(   );
     if (st != OK) {
            return st;
     }

     st = bar_ccc(   );
     if (st != OK) {
            return st;
     }

  return st;
  }


A much cleaner method that I've been using for many years is as follows:


Code:
status   foo(    )
{
      status st = OK;
  
     st = bar_aaa(   ); ER_CHK(st);
     st = bar_bbb(   ); ER_CHK(st);
     st = bar_ccc(   ); ER_CHK(st);

ER_EXIT:

    return st;

}

ER_CHK is a macro that is defined as follows: (simplified)

Code:
#define ER_CHK(st) if (st != OK) goto ER_EXIT; else ;


However the use of the \"goto\" makes people shudder and point to appropriate section in MISRA - though shall not GOTO

My question

Is such a use of GOTO allowed ?
Justification:

1. The GOTO is hidden in a macro and execution proceeds to a well defined point - this is as structured as the the jump commands behind the f,while, switch - and yes - break statements. It is better than the break since the destination is well known

2. The ER_CHK macro can be viewed as an extension of C

3. It provides a single exit point. This is a major problem in the \"return\" method since if there is a resource to release it needs to be done before each return.

4. The code is MUCH cleaner and robust

5. The actual goto was outlawed because it's use lead to a mess - this use prevents the mess - and is more robust since the programmer does not deal with the \"ifs\" and \"returns\" - so can't introduce bugs by doing it wrongly ( \"=\" vs \"==\" bugs, no bug fogetting the \"return\" or doing cleanup before the return etc.)

6. ER_CHK is actully defined as

Code:
#define ER_CHK(st) if (st != OK)         {write_to_log(__LINE__, __FILE__); goto ER_EXIT; else ;

So the log contains something like

foo1.c (23) status = 3;
foo2.c (125) status = 3;
foo3.c (13) status = 3;

Where a function in foo3.c on line 13 calls a function in foo2.c on line 125 etc.

Even C++, Jave exceptions don't do that !!

The attatched article provides more details and shows an implementation that is CPU and Memory efficient.

Again - the quesion I'm asking is that the use of this mechanism illegal in MISRA ?
ylehman Wrote:
Code:
status   foo(    )
{
      status st = OK;
  
     st = bar_aaa(   ); ER_CHK(st);
     st = bar_bbb(   ); ER_CHK(st);
     st = bar_ccc(   ); ER_CHK(st);

ER_EXIT:

    return st;

}

ER_CHK is a macro that is defined as follows: (simplified)

Code:
#define ER_CHK(st) if (st != OK) goto ER_EXIT; else ;

[...]
Is such a use of GOTO allowed ?


This clearly isn't MISRA compliant. You can't goto. (You also need braces on your if-controlled statements, and brackets around "(st)".)

But if you want to do this then just raise a deviation. It shouldn't be hard to justify.

stephen
As wrote by sparker: it isn't MISRA.

But just two remarks:

Quote:3. It provides a single exit point. This is a major problem in the "return" method since if there is a resource to release it needs to be done before each return.
All resources should not be got on function entry. So the resources to release on exit point, may be dependent to the executed path.

ylehman Wrote:4. The code is MUCH cleaner and robust
I'm not agree because the control flow is hidden and not clear:
The code appears like a functions call sequence (only one code path), but in fact no! Otherwise, this tips may come less readable when the bar_aaa function will be callded inside a nested conditionnal test.
1) The normal way to solve the above problem is a flag

foo( )
{
int sem_is_locked = FALSE;

LOCK(sem); sem_is_locked = TRUE;


ER_EXIT:
if (sem_is_locked)
UNLOCK(sem)

}

In some cases, this type of technique would be necessary even if you don't use the macros.


2) I understand your comment,

Quote:The code appears like a functions call sequence (only one code path), but in fact no

however in practice the use of the macro is not isolated so that the programmer needs to work out what to do. It appears on every line where these is a function call. It is a system wide idiom which becomes part of the language - in fact it used more often then \"if\"s and \"while\"s - think of it as a language extension.

3) my real question is not is it part of MISRA - the real question is why it isn't - I claim that is should be mandated :-)

There is no doubt that it leads to cleaner and more robust code - my examples are simple - the more complex the code - the more it is justified
In the end of the day - isn't this MISRAs goal ?

Is MISRA carved in stone or is there a process to change MISRA ?

Another comment;

The same technique is used to do have a single exit point instead of doing \"returns\" in the middle of the code, or using complicated if structures.

What do you think of this use ? The alternatives are much less robust and less readable.



[/u]
Your example shows a defensible use of goto statements, and therefore could be a justifiable deviation.
Is that an official \"misra\" statement that I can use if I am confronted by the \"goto is illegal\" dogma :-) when trying to introduce such a macro ?

Thanks
ylehman Wrote:Is that an official "misra" statement that I can use if I am confronted by the "goto is illegal" dogma :-) when trying to introduce such a macro ?

Thanks

What they have said is you can probably deviate in that situation which is a bit of a cop out. Actually you can deviate any rule.

The question is can you write a deviation that will stand up to external scrutiny in 1 or 2 years time by person(s) not on the development team?

It’s easy to write a deviation that you think is good now but unless the rest of the team and management agree you will be sunk if anything goes wrong.

MISRA is not a religeon but Engineering. It shopuld not be chanted like dogma nor swayed by fashion.