Multiple returns in functions

  • Follow


What is a good programming style in C to handle multiple returns in a
function that returns different values?
- To have a variable that is set to the return value, which is in the
end of  the function returned?
- To have multiple returns with different values?

Which to prefer, and is there a better way?

/nergal

0
Reply nergal (18) 3/16/2007 7:52:00 AM

nergal wrote:
> What is a good programming style in C to handle multiple returns in a
> function that returns different values?
> - To have a variable that is set to the return value, which is in the
> end of  the function returned?
> - To have multiple returns with different values?
> 
> Which to prefer, and is there a better way?
> 
Probably a point of style, but due to the absence of any clean up
mechanism in C, I prefer a C function to have a single return.

It's easier to debug (only one place to set a breakpoint), saves hunting
for multiple returns and makes life much easier if the function has to
release any locks or other resources before it returns.

-- 
Ian Collins.
0
Reply ian-news (9908) 3/16/2007 7:59:51 AM


nergal said:

> What is a good programming style in C to handle multiple returns in a
> function that returns different values?
> - To have a variable that is set to the return value, which is in the
> end of  the function returned?
> - To have multiple returns with different values?
> 
> Which to prefer, and is there a better way?

Opinions vary. I favour a single return statement, and I'm not alone in 
that. Why? Because I think it makes the code easier to understand. But 
many people prefer to return as soon as possible. Why? Because they 
think it makes the code easier to understand!

This is not a matter of correctness, but of style. So - you choose.

-- 
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
0
Reply rjh (10789) 3/16/2007 8:01:43 AM

On Mar 16, 12:52 pm, "nergal" <ner...@nergal.se> wrote:
> What is a good programming style in C to handle multiple returns in a
> function that returns different values?
> - To have a variable that is set to the return value, which is in the
> end of  the function returned?
> - To have multiple returns with different values?
>
> Which to prefer, and is there a better way?

Program which seems easy to you. For time optimization, you can choose
multiple return statements in the function.

-N

0
Reply naresh.attri (64) 3/16/2007 8:04:11 AM

Nishu said:

> On Mar 16, 12:52 pm, "nergal" <ner...@nergal.se> wrote:
>> What is a good programming style in C to handle multiple returns in a
>> function that returns different values?
>> - To have a variable that is set to the return value, which is in the
>> end of  the function returned?
>> - To have multiple returns with different values?
>>
>> Which to prefer, and is there a better way?
> 
> Program which seems easy to you. For time optimization, you can choose
> multiple return statements in the function.

No. Use whichever you think is *clearer* to the reader - and be 
consistent. Using multiple returns as a time optimisation is premature. 
The chances of it being your bottleneck are vanishingly low.

-- 
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
0
Reply rjh (10789) 3/16/2007 8:12:45 AM

On Mar 16, 12:52 pm, "nergal" <ner...@nergal.se> wrote:
> What is a good programming style in C to handle multiple returns in a
> function that returns different values?
> - To have a variable that is set to the return value, which is in the
> end of  the function returned?
> - To have multiple returns with different values?
>
> Which to prefer, and is there a better way?
>
> /nergal

Preferably single return value over multiple return statements spread
across. Steve McCullen in his book 'Code Complete' also recommends
using single return statement as much as possible.

Cheers
-Vallabha
S7 Software Solutions
http://www.s7solutions.com

0
Reply vsnadagouda (25) 3/16/2007 10:02:02 AM

"nergal" <nergal@nergal.se> wrote:

> What is a good programming style in C to handle multiple returns in a
> function that returns different values?
> - To have a variable that is set to the return value, which is in the
> end of  the function returned?
> - To have multiple returns with different values?

That depends on what the multiple returns are for. If they're for early
bail-outs for erroneous or border-case input (e.g., a list sorting
function returning early when the list is empty, or a point plotting
function bailing out with an error code when the point is off the
screen), I'd use multiple returns. If they're actual different paths
through the function, I'd use a variable. Often, I'd use both in the
same function. Like this:

  int function(int value, char *name)
  {
    int factor;
    int retval;

    if (value<0)
      return 0;
    if (!name || !*name)
      return 0;

    retval=value;
    if (strlen(procustrate(name))>NAME_LIMIT) {
      factor=2;
      /* Do some complicated computations on factor here. */
      retval/=factor;
    } else {
      factor=nominal_value(name);
      /* Do some more computations on factor here. */
      retval*=factor;
    }

    return retval;
  }

Richard
0
Reply rlb (4118) 3/16/2007 10:20:23 AM

nergal wrote:

> What is a good programming style in C to handle multiple returns in a
> function that returns different values?
> - To have a variable that is set to the return value, which is in the
> end of  the function returned?
> - To have multiple returns with different values?
> 
> Which to prefer, and is there a better way?

Prefer whichever one makes the code clearer.

(I find that means it's /usually/ a single return, but sometimes
 when C's syntax would make this clumsy, eg by requiring an
 extra variable, then I have no hesitation in using multiple
 returns. A common form of the exceptional case is the search:

   for each element E of something do
      if E's the one then return some computation over E
   return whatever shows the search found nothing

 The game of trying to do this with a single return is,
 IMAO, not worth the candle.
)

(Arguments that say "in a big function you may lose track of
 those extra returns" I respond to with "such a function is
 already too big: fix that first." Humble I reserve for pies.)

-- 
Chris "spiky and sparky hedgehog" Dollin
The shortcuts are all full of people using them.

0
Reply chris.dollin (1683) 3/16/2007 11:07:02 AM

In article <1174031520.081805.68120@e65g2000hsc.googlegroups.com>,
nergal <nergal@nergal.se> wrote:

>What is a good programming style in C to handle multiple returns in a
>function that returns different values?
>- To have a variable that is set to the return value, which is in the
>end of  the function returned?
>- To have multiple returns with different values?

I wouldn't have bothered to reply to this, but since the replies are
generally in favour of single returns, I'll weigh in on the other
side.

I find the multiple return form clearer in most cases.  It matches
the common mathematical notation for functions:

        { 1         if n == 0
   n! = {
        { n.(n-1)!  otherwise

it also generally uses less vertical space, which makes the overall
structure of a function easier to grasp.

Of course, if there's some kind of common cleanup to be done, it's
usually clearer to put it all in one place before a single return,
perhaps with a label so that nested branches can goto it.

-- Richard
-- 
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
0
Reply richard91 (3683) 3/16/2007 11:50:39 AM

On Mar 16, 2:52 am, "nergal" <ner...@nergal.se> wrote:
> What is a good programming style in C to handle multiple returns in a
> function that returns different values?
> - To have a variable that is set to the return value, which is in the
> end of  the function returned?
> - To have multiple returns with different values?
>
> Which to prefer, and is there a better way?
>
> /nergal

Code whichever you think will be clearer to the human reader.
Ignore anything to do with efficiency (the chance of this
decision making a measurable difference are very small
indeed).

I am in the "single return point" camp
(both for readability and "clean up" code reasons.
However, opinions on this point vary.


                   - William Hughes


0
Reply wpihughes (390) 3/16/2007 12:30:26 PM

Richard Heathfield wrote, On 16/03/07 08:12:
> Nishu said:
> 
>> On Mar 16, 12:52 pm, "nergal" <ner...@nergal.se> wrote:
>>> What is a good programming style in C to handle multiple returns in a
>>> function that returns different values?
>>> - To have a variable that is set to the return value, which is in the
>>> end of  the function returned?
>>> - To have multiple returns with different values?
>>>
>>> Which to prefer, and is there a better way?
>> Program which seems easy to you. For time optimization, you can choose
>> multiple return statements in the function.
> 
> No. Use whichever you think is *clearer* to the reader - and be 
> consistent. Using multiple returns as a time optimisation is premature. 
> The chances of it being your bottleneck are vanishingly low.

The chances of the compiler not doing the optimisation if it is 
appropriate are even lower!

Definitely write the code for clarity first and foremost.
-- 
Flash Gordon
0
Reply spam331 (4024) 3/16/2007 12:32:05 PM

On Mar 16, 11:50 am, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
> In article <1174031520.081805.68...@e65g2000hsc.googlegroups.com>,
>
> nergal <ner...@nergal.se> wrote:
> >What is a good programming style in C to handle multiple returns in a
> >function that returns different values?
> >- To have a variable that is set to the return value, which is in the
> >end of  the function returned?
> >- To have multiple returns with different values?
>
> I wouldn't have bothered to reply to this, but since the replies are
> generally in favour of single returns, I'll weigh in on the other
> side.
>
> I find the multiple return form clearer in most cases.  It matches
> the common mathematical notation for functions:
>
>         { 1         if n == 0
>    n! = {
>         { n.(n-1)!  otherwise
>
> it also generally uses less vertical space, which makes the overall
> structure of a function easier to grasp.
>
> Of course, if there's some kind of common cleanup to be done, it's
> usually clearer to put it all in one place before a single return,
> perhaps with a label so that nested branches can goto it.

in such a scenario, rather than using goto I use this idiom:

int success = 0;
do
{  if (hell_breaks_loose) {
      break;
   }
   do_stuff();
   if (dire_straits) {
      break;
   }
   et_cetera();
   success = 1;
} while (0);

if (!success) {
   /* cleanup */
}

I find the sequence of events easy to follow this way. The block, the
success variable and the break statements map well onto the high level
description of the code.

Stijn

0
Reply micans (36) 3/16/2007 1:07:49 PM

On Mar 16, 3:52 pm, "nergal" <ner...@nergal.se> wrote:
> What is a good programming style in C to handle multiple returns in a
> function that returns different values?
> - To have a variable that is set to the return value, which is in the
> end of  the function returned?
> - To have multiple returns with different values?
>
> Which to prefer, and is there a better way?
>
> /nergal

My general experience is that single point of return code has been
much easier to maintain. Some changes in an already existing code were
much easier to do when I converted the multiple returns into single
return. Single point of return also means that we know exactly where
the function will return.

0
Reply kah.goh (17) 3/16/2007 3:02:45 PM

nergal wrote:
> What is a good programming style in C to handle multiple returns in a
> function that returns different values?
> - To have a variable that is set to the return value, which is in the
> end of  the function returned?
> - To have multiple returns with different values?
> 
> Which to prefer, and is there a better way?

Check the archives of this newsgroup.  There was a skirmish in this holy 
not too long ago.
0
Reply clvrmnky.invalid (895) 3/16/2007 3:21:05 PM

On 16 Mar, 07:52, "nergal" <ner...@nergal.se> wrote:
> What is a good programming style in C to handle multiple
> returns in a function that returns different values?
> - To have a variable that is set to the return value,
> which is in the end of  the function returned?
> - To have multiple returns with different values?
>
> Which to prefer, and is there a better way?

In my programming career, I frequently saw code
which had been distorted into illegibility by
the pathological requirement to return only at
the end of the function.  Typically, it would be
riddled with Booleans, or tests for NULL, which
meant no more than "don't do this block".

Yes, multiple returns create a tidying-up problem,
but it is soluble with a structure holding all
the tidy-up information, and a tidy-up function
to use as much of it as has been initialised.

Thus, instead of:
      return some_val;
we write:
      return tidy_up (tidy_struct, some_val);

where tidy_up( ) returns some_val, after it has
made the correct use of every non-NULL element
found in tidy_struct{ }.  On an early return,
there will be few of these, or none.
--

0
Reply bert.hutchings (56) 3/16/2007 4:52:18 PM

Chris Dollin wrote:
 
> (Arguments that say "in a big function you may lose track of
>  those extra returns" I respond to with "such a function is
>  already too big: fix that first." Humble I reserve for pies.)

I think that multiple returns are best suited to very small functions.

int memcmp(const void *s1, const void *s2, size_t n)
{   
    const unsigned char *p1 = s1;
    const unsigned char *p2 = s2;

    for (;;) {
        if (n-- == 0) {
            return 0;
        }
        if (*p1 != *p2) {
            return *p2 > *p1 ? -1 : 1;
        }
        ++p1;
        ++p2;
    }
}

int strcmp(const char *s1, const char *s2)
{
    const unsigned char *p1 = (const unsigned char *)s1;
    const unsigned char *p2 = (const unsigned char *)s2;

    for (;;) {
        if (*p1 != *p2) {            
            return *p2 > *p1 ? -1 : 1;
        }
        if (*p1 == '\0') {
            return 0;
        }
        ++p1;
        ++p2;
    }
}

int strncmp(const char *s1, const char *s2, size_t n)
{    
    const unsigned char *p1 = (const unsigned char *)s1;
    const unsigned char *p2 = (const unsigned char *)s2;

    for (;;) {
        if (n-- == 0) {
            return 0;
        }
        if (*p1 != *p2) {            
            return *p2 > *p1 ? -1 : 1;
        }
        if (*p1 == '\0') {
            return 0;
        }        
        ++p1;
        ++p2;        
    }
}

-- 
pete
0
Reply pfiland (6614) 3/18/2007 1:33:51 AM

Richard Bos wrote:
> "nergal" <nergal@nergal.se> wrote:
> 
>> What is a good programming style in C to handle multiple returns in a
>> function that returns different values?
>> - To have a variable that is set to the return value, which is in the
>> end of  the function returned?
>> - To have multiple returns with different values?
> 
> That depends on what the multiple returns are for. If they're for early
> bail-outs for erroneous or border-case input (e.g., a list sorting
> function returning early when the list is empty, or a point plotting
> function bailing out with an error code when the point is off the
> screen), I'd use multiple returns. If they're actual different paths
> through the function, I'd use a variable. Often, I'd use both in the
> same function. Like this:


Your example is good because it shows there is a tradeoff between
logical nesting depth and the  use of extra return values.  For smallish
code, like this example, a bit of extra nesting isn't a problem and so
a single exit helps.  However, I've run into functions nested very deep
and thousands of lines long.  In those cases it's often easier to follow 
the logic if explicit returns break the code up into smaller blocks.
(One could also argue that these large functions should just be 
rewritten into several smaller ones.) Here is your example slightly 
edited to illustrate this point, going with greater nesting instead
of early returns:

>   int function(int value, char *name)
>   {
>     int factor;
>     int retval=0;
> 
>     if (value<0){
          retval=-1;
       }
       else if(!name){
          retval=-2;
       }
       else if(!*name){
          retval=-3;
       }
       else {
indent one level here
>     retval=value;
>     if (strlen(procustrate(name))>NAME_LIMIT) {
>       factor=2;
>       /* Do some complicated computations on factor here. */
>       retval/=factor;
>     } else {
>       factor=nominal_value(name);
>       /* Do some more computations on factor here. */
>       retval*=factor;
>     }
unindent one level here
       }
> 
>     return retval;
>   }


That said, for anything over a few hundred lines I prefer parameter 
checking followed immediately by a return over the form shown above.
That way all of the logic associated with that parameter checking fits 
on one screen and it's obvious what is going on.  Once the code is a 
couple of hundred lines long the programmer has to scan down who knows 
how far to find out what's at the other end of the dangling "{", and 
searching for the "other end" makes the code harder to maintain.

Regards,

David Mathog
0
Reply mathog (321) 3/19/2007 3:49:02 PM

David Mathog wrote:

> Your example is good because it shows there is a tradeoff between
> logical nesting depth and the  use of extra return values.  For smallish
> code, like this example, a bit of extra nesting isn't a problem and so
> a single exit helps.  However, I've run into functions nested very deep
> and thousands of lines long.  In those cases it's often easier 

.... to break the bagger up into smaller functions and suggest to the
entity that wrote it that not everyone has a brain as big as theirs.

-- 
Chris "electric hedgehog" Dollin
"Life is full of mysteries. Consider this one of them." Sinclair, /Babylon 5/

0
Reply chris.dollin (1683) 3/19/2007 4:00:24 PM

17 Replies
27 Views

(page loaded in 0.262 seconds)


Reply: