Click here to Skip to main content
15,121,540 members
Articles / Programming Languages / C++
Tip/Trick
Posted 1 May 2021

Tagged as

Stats

3.6K views

Adhering to a Silly Rule

Rate me:
Please Sign up or sign in to vote.
3.80/5 (6 votes)
1 May 2021CPOL1 min read
A function may only return from its last line!
Some coding standards insist that a function only return at its end. However, there is a way to simplify the convoluted code that this often produces.

Introduction

Some coding standards, including MISRA, insist that a function only return from its end. This often results in a flag being used to bypass each subsequent condition and eventually reach the return statement. Fortunately, there is an idiom—also useful in the middle of a function—that can mitigate this dross.

Using the Code

Have you ever worked on code like this?

C++
<type> Function(...)
{
   <type> result = <default>;
   bool done = false;

   if(condition1)
   {
      result = <something>;
      done = true;

   }

   if(!done && condition2)
   {
      result = <something else>;
      done = true;
   }

   ...

   if(!done && conditionN)
   {
      result = <something completely different>;
      done = true;
   }

   return result;
}

Or even worse, code that does the above by nesting condition statements so deeply that you have to use the horizontal scroll bar to read the code way over on the right?

Some folks actually believe this improves quality so much that they mandate it. If you find it as imbecilic as I do, here's a way to improve the code while still observing the rule.

No, we're not about to use goto to reach the return statement. Although that would be an improvement, the standard probably prohibits it too.

So instead, do this:

C++
<type> Function(...)
{
   <type> result = <default>;

   do
   {
      if(condition1)
      {
         result = <something>;
         break;
      }

      if(condition2)
      {
         result = <something else>;
         break;
      }

      ...

      if(conditionN)
      {
         result = <something completely different>;
         break;
      }
   } while(false);

   return result;
}

That's similar to the goto solution, but I doubt your standard will have anything rude to say about it. Having to use this idiom in this situation is still unfortunate, but it's the best of a bad lot.

The idiom can be very useful in middle of a function. For example, I have a C++ parser in which the following code parses a class tempate instance:

C++
bool Parser::ParseClassInst(ClassInst* inst, size_t pos)
{
   auto name = inst->ScopedName(true);
   Debug::Progress(CRLF + Indent() + name);

   //  Initialize the parser. If an "object code" file is being produced,
   //  insert the instance name.

   Enter(IsClassInst, name, inst->GetTemplateArgs(), inst->GetCode(), true);
   lexer_.Reposition(pos);
   Context::Trace(CxxTrace::START_TEMPLATE, inst);

   //  Push the template instance as the current scope and start to parse it.
   //  The first thing that could be encountered is a base class declaration.
   do
   {
      BaseDeclPtr base;
      Context::PushScope(inst, false);
      GetBaseDecl(base);
      if(!lexer_.NextCharIs('{')) break;
      inst->AddBase(base);
      GetMemberDecls(inst);
      Context::PopScope();
      if(!lexer_.NextCharIs('}')) break;
      if(!lexer_.NextCharIs(';')) break;
      GetInlines(inst);
   }
   while(false);

   //  The parse succeeded if the lexer reached the end of the code.  If the
   //  parse failed, indicate this on the console.  If an "object code" file
   //  is being produced, indicate that parsing of the template is complete.

   auto parsed = lexer_.Eof();
   Debug::Progress((parsed ? EMPTY_STR : " **FAILED** "));
   if(!parsed) Failure(venue_);
   Context::Trace(CxxTrace::END_TEMPLATE);
   return parsed;
}

Granted, that's not a great example. A better (but more complicated) one involves resolving each identifier in a qualified name. That do {...} while(false); occurs in one case of a while-switch loop and handles an identifier that names a class template instance, so it really helps to keep the code manageable. But I hope the above  illustrates the point.

Best of luck in your code review!

History

  • 1st May, 2021: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Greg Utas
Architect
Canada Canada
Author of Robust Services Core (GitHub) and Robust Communications Software (Wiley, 2005). Formerly Chief Software Architect of the core network servers that handle the calls in AT&T's wireless network.

Comments and Discussions

 
GeneralMy vote of 3 Pin
pierrecoach3-May-21 22:19
professionalpierrecoach3-May-21 22:19 
GeneralRe: My vote of 3 Pin
Greg Utas4-May-21 12:53
mvaGreg Utas4-May-21 12:53 
QuestionSilly rule indeed Pin
Gary R. Wheeler3-May-21 14:21
MemberGary R. Wheeler3-May-21 14:21 
AnswerRe: Silly rule indeed Pin
Greg Utas4-May-21 12:45
mvaGreg Utas4-May-21 12:45 
GeneralRe: Silly rule indeed Pin
Gary R. Wheeler4-May-21 13:30
MemberGary R. Wheeler4-May-21 13:30 
QuestionThere is a simple solution to this silly rule. Pin
wa1gon13-May-21 13:54
Memberwa1gon13-May-21 13:54 
AnswerRe: There is a simple solution to this silly rule. Pin
Greg Utas4-May-21 12:40
mvaGreg Utas4-May-21 12:40 
QuestionReturn at end Pin
david garlisch3-May-21 13:26
Memberdavid garlisch3-May-21 13:26 
AnswerRe: Return at end Pin
wa1gon14-May-21 5:30
Memberwa1gon14-May-21 5:30 
AnswerRe: Return at end Pin
Greg Utas4-May-21 12:26
mvaGreg Utas4-May-21 12:26 
GeneralMy vote of 4 Pin
Rusty Bullet3-May-21 9:21
MemberRusty Bullet3-May-21 9:21 
PraiseI like this... Pin
Michael Breeden3-May-21 9:04
MemberMichael Breeden3-May-21 9:04 
This looks useful but discussion between myself C# and an even more experienced C++ developer, concluded that actually using goto inside of a method seemed sensible.

Questionelse if? Pin
Pete Lomax Member 106645053-May-21 2:28
professionalPete Lomax Member 106645053-May-21 2:28 
AnswerRe: else if? Pin
Greg Utas3-May-21 3:13
mvaGreg Utas3-May-21 3:13 
GeneralRe: else if? Pin
Pete Lomax Member 106645053-May-21 4:40
professionalPete Lomax Member 106645053-May-21 4:40 
GeneralRe: else if? Pin
Greg Utas3-May-21 5:11
mvaGreg Utas3-May-21 5:11 
QuestionBut it remains a silly rule Pin
Joerg Michels3-May-21 0:01
MemberJoerg Michels3-May-21 0:01 
AnswerRe: But it remains a silly rule Pin
AllenR3-May-21 22:41
professionalAllenR3-May-21 22:41 
AnswerRe: But it remains a silly rule Pin
Member 1194113125-May-21 12:34
MemberMember 1194113125-May-21 12:34 
GeneralRe: But it remains a silly rule Pin
Joerg Michels25-May-21 21:54
MemberJoerg Michels25-May-21 21:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.