repeated code before multiple return statements

Discussion in 'C Programming' started by Alexander Stoyakin, Jul 27, 2007.

  1. Hello!
    Please advise on the following issue. I have a function which returns
    1 or 0 in multiple branches, and it must perform the same code before
    each return, like this:
    int fun()
    {
    if (some code)
    {
    restore(param1,param2,param3,param4,param5);
    return 1;
    }
    else if (some code)
    {
    restore(param1,param2,param3,param4,param5);
    return 0;
    }
    restore(param1,param2,param3,param4,param5);
    return 1;
    }

    Is there any alternative way to execute some code upon return from the
    function in pure C? Repeated code makes my function more than twice
    longer and it losts its readability. The only thing coming to my mind
    is goto.

    Thanks, Alex.
    Alexander Stoyakin, Jul 27, 2007
    #1
    1. Advertising

  2. Alexander Stoyakin wrote:
    >
    > Hello!
    > Please advise on the following issue. I have a function which returns
    > 1 or 0 in multiple branches, and it must perform the same code before
    > each return, like this:
    > int fun()
    > {
    > if (some code)
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    > }
    > else if (some code)
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 0;
    > }
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    > }
    >
    > Is there any alternative way to execute some code upon return from the
    > function in pure C? Repeated code makes my function more than twice
    > longer and it losts its readability. The only thing coming to my mind
    > is goto.


    What about something like this?

    int fun()
    {
    int retval;

    if ( some code )
    retval = 1;
    else if ( some other code )
    retval = 0;
    else
    retval = 1;

    restore(param1, param2, param3, param4, param5);

    return retval;
    }

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Jul 27, 2007
    #2
    1. Advertising

  3. Alexander Stoyakin

    Ben Pfaff Guest

    Alexander Stoyakin <> writes:

    > Please advise on the following issue. I have a function which returns
    > 1 or 0 in multiple branches, and it must perform the same code before
    > each return, like this:
    > int fun()
    > {
    > if (some code)
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    > }
    > else if (some code)
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 0;
    > }
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    > }


    int fun2()
    {
    if (some code)
    return 1;
    else if (some code)
    return 0;
    else
    return 1;
    }

    int fun()
    {
    int retval = fun2();
    restore(param1,param2,param3,param4,param5);
    return retval;
    }
    --
    Go not to Usenet for counsel, for they will say both no and yes.
    Ben Pfaff, Jul 27, 2007
    #3
  4. On Jul 27, 2:00 pm, Kenneth Brody <> wrote:

    > What about something like this?
    >
    > int fun()
    > {
    > int retval;
    >
    > if ( some code )
    > retval = 1;
    > else if ( some other code )
    > retval = 0;
    > else
    > retval = 1;
    >
    > restore(param1, param2, param3, param4, param5);
    >
    > return retval;
    > }


    How about

    int retval = ( some_code || !some_other_code ) ? 1 : 0;

    restore(param1, param2, param3, param4, param5);
    return retval;

    ?

    (Depending on what some_code and some_other_code actually are, this
    may not be readable in practice.)
    C. Benson Manica, Jul 27, 2007
    #4
  5. Alexander Stoyakin wrote:
    >..I have a function which returns
    >1 or 0 in multiple branches, and it must perform the same code before
    >each return, like this:
    >int fun()
    >{
    > if (some code)

    /* let's call this condition_1 */
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    > }
    > else if (some code)

    /* let's call this condition_2 */
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 0;
    > }
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    >}
    >
    >Is there any alternative way to execute some code upon return from the
    >function in pure C? Repeated code makes my function more than twice
    >longer and it losts its readability. The only thing coming to my mind
    >is goto.


    Assuming the parameter lists param1..5 are identical, you wrote this:

    int fun()
    {
    int ret_val = 1;
    if (condition_1)
    {
    }
    else if (condition_2)
    {
    ret_val = 0;
    }
    restore(param1,param2,param3,param4,param5);
    return ret_val
    }

    Assuming "condition_1" and "condition_2" do not contain function calls
    or have side effects, you wrote this:

    int fun()
    {
    int ret_val = 1;
    if (condition_2)
    {
    ret_val = 0;
    }
    restore(param1,param2,param3,param4,param5);
    return ret_val
    }


    Roberto Waltman

    [ Please reply to the group,
    return address is invalid ]
    Roberto Waltman, Jul 27, 2007
    #5
  6. Alexander Stoyakin

    santosh Guest

    Alexander Stoyakin wrote:

    > Hello!
    > Please advise on the following issue. I have a function which returns
    > 1 or 0 in multiple branches, and it must perform the same code before
    > each return, like this:
    > int fun()
    > {
    > if (some code)
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    > }
    > else if (some code)
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 0;
    > }
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    > }
    >
    > Is there any alternative way to execute some code upon return from the
    > function in pure C? Repeated code makes my function more than twice
    > longer and it losts its readability. The only thing coming to my mind
    > is goto.


    Two possibilities, among others:

    int fun()
    {
    int retcode;

    if(exp1) retcode = 1;
    else if(exp2) retcode = 0;
    else retcode = 1;

    restore(p1, p2, p3, p4, p5);
    return retcode;
    }

    or

    int fun()
    {
    restore(p1, p2, p3, p4, p5);
    if (exp1) return 1;
    else if (exp2) return 0;
    else return 1;
    }

    HTH
    santosh, Jul 27, 2007
    #6
  7. In article <>,
    Roberto Waltman <> wrote:

    >Assuming the parameter lists param1..5 are identical, you wrote this:


    >int fun()
    >{
    > int ret_val = 1;
    > if (condition_1)
    > {
    > }
    > else if (condition_2)
    > {
    > ret_val = 0;
    > }
    > restore(param1,param2,param3,param4,param5);
    > return ret_val
    >}


    >Assuming "condition_1" and "condition_2" do not contain function calls
    >or have side effects, you wrote this:


    >int fun()
    >{
    > int ret_val = 1;
    > if (condition_2)
    > {
    > ret_val = 0;
    > }
    > restore(param1,param2,param3,param4,param5);
    > return ret_val
    >}


    Let condition_1 be param1 == 0
    Let condition_2 be 1/param1 > param2
    Then condition_1 and condition_2 do not contain function calls
    or have side effects, but your revised code would go directly to

    if (1/param1 > param2)
    {
    ret_val = 0;
    }

    which is going to fail if param1 is 0 -- the condition protected
    against in condition_1 .

    --
    There are some ideas so wrong that only a very intelligent person
    could believe in them. -- George Orwell
    Walter Roberson, Jul 27, 2007
    #7
  8. On Fri, 27 Jul 2007 14:00:43 -0400, Kenneth Brody wrote:
    >What about something like this?
    >
    > int fun()
    > {
    > int retval;


    ....

    > return retval;
    > }


    a.k.a. SESE (Single Entry, Single Exit)


    --
    Roland Pibinger
    "The best software is simple, elegant, and full of drama" - Grady Booch
    Roland Pibinger, Jul 27, 2007
    #8
  9. Alexander Stoyakin

    CBFalconer Guest

    Alexander Stoyakin wrote:
    >
    > Please advise on the following issue. I have a function which returns
    > 1 or 0 in multiple branches, and it must perform the same code before
    > each return, like this:
    > int fun()
    > {
    > if (some code)
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    > }
    > else if (some code)
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 0;
    > }
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    > }
    >
    > Is there any alternative way to execute some code upon return from the
    > function in pure C? Repeated code makes my function more than twice
    > longer and it losts its readability. The only thing coming to my mind
    > is goto.


    int fun() {
    int flag;

    flag = 1;
    if (some code) flag = 1;
    else if (some other code) flag = 0;
    restore(.....);
    return flag;
    }

    --
    <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
    <http://www.securityfocus.com/columnists/423>
    <http://www.aaxnet.com/editor/edit043.html>
    cbfalconer at maineline dot net


    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Jul 27, 2007
    #9
  10. santosh <> wrote:

    > int retcode;
    >
    > if(exp1) retcode = 1;
    > else if(exp2) retcode = 0;
    > else retcode = 1;


    > restore(p1, p2, p3, p4, p5);


    Given this...

    > restore(p1, p2, p3, p4, p5);
    > if (exp1) return 1;
    > else if (exp2) return 0;
    > else return 1;


    ....it seems unlikely (but possible) that OP will want to restore()
    anything prior to the evaluation of exp1 and exp2.

    --
    C. Benson Manica | I appreciate all corrections, polite or otherwise.
    cbmanica(at)gmail.com |
    ----------------------| I do not currently read any posts posted through
    sdf.lonestar.org | Google groups, due to rampant unchecked spam.
    Christopher Benson-Manica, Jul 27, 2007
    #10
  11. Alexander Stoyakin

    Al Balmer Guest

    On Fri, 27 Jul 2007 18:10:07 -0000, "C. Benson Manica"
    <> wrote:

    >On Jul 27, 2:00 pm, Kenneth Brody <> wrote:
    >
    >> What about something like this?
    >>
    >> int fun()
    >> {
    >> int retval;
    >>
    >> if ( some code )
    >> retval = 1;
    >> else if ( some other code )
    >> retval = 0;
    >> else
    >> retval = 1;
    >>
    >> restore(param1, param2, param3, param4, param5);
    >>
    >> return retval;
    >> }

    >
    >How about
    >
    >int retval = ( some_code || !some_other_code ) ? 1 : 0;
    >
    >restore(param1, param2, param3, param4, param5);
    >return retval;
    >

    That will work for "this", but no necessarily "something like this"
    :) I think the OPs example was intended to be illustrative, not
    necessarily his exact need.

    Kenneth's solution is good, and easily generalized. Both solutions
    have the desirable feature of making it plain that the "some (other)
    code" affects only the return value, not the processing, and
    eliminating multiple returns. (I'm not always opposed to multiple
    returns, but there's no excuse for them here.)
    >?
    >
    >(Depending on what some_code and some_other_code actually are, this
    >may not be readable in practice.)


    --
    Al Balmer
    Sun City, AZ
    Al Balmer, Jul 27, 2007
    #11
  12. Al Balmer <> wrote:

    > On Fri, 27 Jul 2007 18:10:07 -0000, "C. Benson Manica"
    > <> wrote:


    > >int retval = ( some_code || !some_other_code ) ? 1 : 0;
    > >
    > >restore(param1, param2, param3, param4, param5);
    > >return retval;


    > That will work for "this", but no necessarily "something like this"
    > :) I think the OPs example was intended to be illustrative, not
    > necessarily his exact need.


    > >(Depending on what some_code and some_other_code actually are, this
    > >may not be readable in practice.)


    I think I covered the possibility that it might not be what OP was
    looking for, and for sure if the real code has many branches the
    conditional operator should be banished from consideration. (This is
    all MHO, incidentally, as I have already been reminded today that I am
    not the Pope...)

    --
    C. Benson Manica | I appreciate all corrections, polite or otherwise.
    cbmanica(at)gmail.com |
    ----------------------| I do not currently read any posts posted through
    sdf.lonestar.org | Google groups, due to rampant unchecked spam.
    Christopher Benson-Manica, Jul 27, 2007
    #12
  13. Alexander Stoyakin

    Gene Guest

    On Jul 27, 1:51 pm, Alexander Stoyakin <> wrote:
    > Hello!
    > Please advise on the following issue. I have a function which returns
    > 1 or 0 in multiple branches, and it must perform the same code before
    > each return, like this:
    > int fun()
    > {
    > if (some code)
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    > }
    > else if (some code)
    > {
    > restore(param1,param2,param3,param4,param5);
    > return 0;
    > }
    > restore(param1,param2,param3,param4,param5);
    > return 1;
    >
    > }
    >
    > Is there any alternative way to execute some code upon return from the
    > function in pure C? Repeated code makes my function more than twice
    > longer and it losts its readability. The only thing coming to my mind
    > is goto.
    >
    > Thanks, Alex.


    Good question. This is one situation that inspired the development (a
    long time ago) of exception mechanisms. To generalize your example a
    little, many functions that honor unix return code standards are
    structured like this...

    int fun(...)
    {
    ...
    if (<condition1>) {
    <cleanup code>
    return 1;
    }
    < normal processing 1 >

    ...
    if (<condition2>) {
    <cleanup code>
    return 2;
    }
    ...
    < normal processing 2>
    ... yada yada ...

    return 0;
    }

    This is really annoying when (as usual) the cleanup code needs access
    to many local variables. In a block structured languate with nested
    functions, you would define a cleanup function with access to those
    variables. In pseudo-C,

    int fun(...)
    {
    <local var decls>

    int cleanup(int return_code)
    {
    <cleanup code>
    return return_code;
    }

    ...
    if (<condition1>) return cleanup(1);

    < normal processing 1 >

    ...

    if (<condition2>) return cleanup(2);

    ...
    < normal processing 2>
    ... yada yada ...

    return 0;
    }

    Since C doesn't have nested functions, one way to go is "fake" them
    with macros. This strategy is far from ideal, but it does have a
    rationale. It avoids the problems of goto's and introducing a very
    long-lived "ret_val" variable, which has maintenance problems.

    int fun(...)
    {
    <local var decls>

    #define CLEANUP_AND_RETURN(N) do { \
    <cleanup code> \
    return (N); \
    } while (0);

    ...
    if (<condition1>) CLEANUP_AND_RETURN(1);

    < normal processing 1 >

    ...

    if (<condition2>) CLEANUP_AND_RETURN(2);

    ...
    < normal processing 2>
    ... yada yada ...

    return 0;

    #undef CLEANUP_AND_RETURN
    }

    Another way to go is bottle up all the local variables needed for
    cleanup in a struct so that a non-nested cleanup function can do its
    work.

    struct foo_vars_s { <local var decls };

    int cleanup(int ret_val, struct foo_vars_s *o)
    {
    <cleanup code accessing variable x as o->x >
    return ret_val;
    }

    int fun()
    {
    struct foo_vars_s o[1];
    < local var ref x is replaced by o->x below >

    ...
    if (<condition1>) return cleanup(1, o);

    < normal processing 1 >

    ...

    if (<condition2>) return cleanup(2, o);

    ...
    < normal processing 2>
    ... yada yada ...

    return 0;
    }

    This isn't ideal either.
    Gene, Jul 28, 2007
    #13
  14. Alexander Stoyakin

    Gene Guest

    On Jul 28, 12:54 pm, Gene <> wrote:

    >
    > #define CLEANUP_AND_RETURN(N) do { \
    > <cleanup code> \
    > return (N); \
    > } while (0);


    Sorry. The last semicolon above is wrong. This should have been

    #define CLEANUP_AND_RETURN(N) do { \
    <cleanup code> \
    return (N); \
    } while (0)

    This trick of using a do { } while(0) wrapper allows macro invocation
    to work as void function calls where a proper statement is expected,
    e.g. in the "then" or "else" of an "if". First saw this in gcc
    sources a long time ago.
    Gene, Jul 29, 2007
    #14
  15. Gene <> writes:
    > On Jul 28, 12:54 pm, Gene <> wrote:
    >
    >>
    >> #define CLEANUP_AND_RETURN(N) do { \
    >> <cleanup code> \
    >> return (N); \
    >> } while (0);

    >
    > Sorry. The last semicolon above is wrong. This should have been
    >
    > #define CLEANUP_AND_RETURN(N) do { \
    > <cleanup code> \
    > return (N); \
    > } while (0)
    >
    > This trick of using a do { } while(0) wrapper allows macro invocation
    > to work as void function calls where a proper statement is expected,
    > e.g. in the "then" or "else" of an "if". First saw this in gcc
    > sources a long time ago.


    See also question 10.4 in the comp.lang.c FAQ, <http://www.c-faq.com/>.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jul 29, 2007
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Neil Zanella
    Replies:
    8
    Views:
    1,169
    mfmehdi
    Oct 20, 2006
  2. Harry George
    Replies:
    6
    Views:
    363
    Bart Nessux
    Feb 23, 2004
  3. Replies:
    24
    Views:
    915
  4. Vince
    Replies:
    12
    Views:
    737
    Martin Gregorie
    Jan 21, 2008
  5. John Crichton
    Replies:
    6
    Views:
    253
    John Crichton
    Jul 12, 2010
Loading...

Share This Page