Returning error values vs. not returning 
Author Message
 Returning error values vs. not returning

Hi All,

I'd like to gather opinions on the merits of the following two functions:

        int foo(char *bar)
        {
                FILE *baz;

                baz = fopen(bar, "r");
                if ( ! baz ) return 0;

                /* do stuff */
                return 1;
        }

vs:

        void foo(char *bar)
        {
                FILE *baz;

                baz = fopen(bar, "r");
                if ( ! baz ) exit(EXIT_FAILURE);

                /* do stuff */
        }

The idea I have had expressed to me is that, given the program that calls
foo() can't continue if foo() fails, one might as well have foo() terminate
the program immediately upon fopen() failing.

Personally, I think this is Bad(tm).  IMO, a function like foo() should
return a failure condition, and the calling program should handle it
gracefully.  *Especially* given that foo() is part of a shared library,
intended for code reuse.

Wotcha all think?

--
Duncan Bayne


     - Web     http://www.*-*-*.com/ ~dhbayne/
     - Cell   (+64) (0)25 626 3023

Once a word has been allowed to escape, it cannot be recalled.
                -- Quintus Horatius Flaccus (Horace)



Sat, 24 Jul 2004 10:20:54 GMT  
 Returning error values vs. not returning


Quote:
>Hi All,

>I'd like to gather opinions on the merits of the following two functions:

>        int foo(char *bar)
>        {
>                FILE *baz;

>                baz = fopen(bar, "r");
>                if ( ! baz ) return 0;

>                /* do stuff */
>                return 1;
>        }

>vs:

>        void foo(char *bar)
>        {
>                FILE *baz;

>                baz = fopen(bar, "r");
>                if ( ! baz ) exit(EXIT_FAILURE);

>                /* do stuff */
>        }

>The idea I have had expressed to me is that, given the program that calls
>foo() can't continue if foo() fails, one might as well have foo() terminate
>the program immediately upon fopen() failing.

This may or may not be true, depending on how foo() fits into the
overall program.

Quote:

>Personally, I think this is Bad(tm).  IMO, a function like foo() should
>return a failure condition, and the calling program should handle it
>gracefully. *Especially* given that foo() is part of a shared library,
>intended for code reuse.

Generally, I agree.  But in cases where foo() isn't part of a shared
library, I think it can be reasonable to exit the program inside
inside functions like foo().  Like this:

/* foo(), bar() and baz() have are very specialized and
  * will only be used in this program */
static void foo(void) { /* If error, exit program */ }
static void bar(void) { /* If error, exit program */ }
static void baz(void) { /* If error, exit program */ }

int main(void)
{
    foo();
    bar();
    baz();
    return 0;

Quote:
}

Russ


Sat, 24 Jul 2004 10:33:32 GMT  
 Returning error values vs. not returning

Quote:

> This may or may not be true, depending on how foo() fits into the
> overall program.

It might be true, but that's no reason to have a library function
arbitrarily take control of the logic flow.

Quote:
> /* foo(), bar() and baz() have are very specialized and
>   * will only be used in this program */
> static void foo(void) { /* If error, exit program */ }
> static void bar(void) { /* If error, exit program */ }
> static void baz(void) { /* If error, exit program */ }

Fair enough.  But I'd still prefer:

        int main(void)
        {
                /* stuff */

                if ( ! foo(void) )
                {
                        /* log stuff and display messages */
                        exit(EXIT_FAILURE);
                }

                /* stuff */
        }

myself.  

--
Duncan Bayne


     - Web    http://homepages.ihug.co.nz/~dhbayne/
     - Cell   (+64) (0)25 626 3023

Once a word has been allowed to escape, it cannot be recalled.
                -- Quintus Horatius Flaccus (Horace)



Sat, 24 Jul 2004 11:22:09 GMT  
 Returning error values vs. not returning

Quote:


> > I'd like to gather opinions on the merits of the following two functions:

> >        int foo(char *bar) {
> >          FILE *baz = fopen(bar, "r");
> >          if (!baz) return EXIT_FAILURE;

> >          /* do stuff */
> >          return EXIT_SUCCESS;
> >          }

> >vs:

> >        void foo(char *bar) {
> >          FILE *baz = fopen(bar, "r");
> >          if (!baz) exit(EXIT_FAILURE);

> >          /* do stuff */
> >          }

> > The idea I have had expressed to me is that
> > given the program that calls foo(char*) can't continue if foo(char*) fails,

> > one might as well have foo(char*) terminate the program
> > immediately upon fopen(const char*, const char*) failing.

> This may or may not be true, depending on how foo(char*) fits into the
> overall program.

> >Personally, I think this is Bad(tm).
> > IMO, a function like foo(char*) should return a failure condition
> > and the calling program should handle it gracefully.
> > *Especially* given that foo(char*) is part of a shared library intended for
> code reuse.

> Generally, I agree.  But, in cases where foo(char*) isn't part of a shared
> library,
> I think it can be reasonable to exit the program inside functions like
> foo(char*).
> Like this:

> /* foo(void), bar(void) and baz(void) have are very specialized
>   * and will only be used in this program */
> static void foo(void) { /* If error, exit program */ }
> static void bar(void) { /* If error, exit program */ }
> static void baz(void) { /* If error, exit program */ }

> int main(int argc, char* argv[]) {
>    foo();
>    bar();
>    baz();
>    return 0;
>   }

Don't return an error code unless you can reasonably expect
the calling function to catch and handle it.
You should never expect the calling function to catch
and handle programming errors (bugs).

Try to handle the error in the local scope if possible.
If you detect a programming error (i.e. bar does not exist),
then you should issue a diagnostic message
to the application programmer but you will still need to decide
whether you should exit the program at that point
or attempt to recover gracefully by doing reasonable stuff.



Sat, 24 Jul 2004 08:35:38 GMT  
 Returning error values vs. not returning

wrote in comp.lang.c:

Quote:
> Hi All,

> I'd like to gather opinions on the merits of the following two functions:

>         int foo(char *bar)
>         {
>                 FILE *baz;

>                 baz = fopen(bar, "r");
>                 if ( ! baz ) return 0;

>                 /* do stuff */
>                 return 1;
>         }

> vs:

>         void foo(char *bar)
>         {
>                 FILE *baz;

>                 baz = fopen(bar, "r");
>                 if ( ! baz ) exit(EXIT_FAILURE);

>                 /* do stuff */
>         }

> The idea I have had expressed to me is that, given the program that calls
> foo() can't continue if foo() fails, one might as well have foo() terminate
> the program immediately upon fopen() failing.

> Personally, I think this is Bad(tm).  IMO, a function like foo() should
> return a failure condition, and the calling program should handle it
> gracefully.  *Especially* given that foo() is part of a shared library,
> intended for code reuse.

> Wotcha all think?

I think it's very, very bad.  It might be acceptable in a very small
program, but certainly not in library code intended for reuse by
different programs in different circumstances.

Even if the program can't continue beyond this failure, it might have
unfinished business to clean up before it exits, such as updates to
data files or log files, displaying reasonable error messages, etc.

To me it seems like a sign of shortsightedness on the part of the
author of a library function to decide what actions will be forced on
any and all programs, function and purpose unknown, that experiences a
particular error.

How does the author of the library function know that any program that
is ever written now or in the future will be unable to continue if
foo() fails?  Why would I want to use a library whose author has
already determined that he knows better than I do how it should
respond to error conditions?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq



Sat, 24 Jul 2004 12:09:31 GMT  
 Returning error values vs. not returning

Quote:

> Hi All,

> I'd like to gather opinions on the merits of the following two functions:

>         int foo(char *bar)
>         {
>                 FILE *baz;

>                 baz = fopen(bar, "r");
>                 if ( ! baz ) return 0;

>                 /* do stuff */
>                 return 1;
>         }

> vs:

>         void foo(char *bar)
>         {
>                 FILE *baz;

>                 baz = fopen(bar, "r");
>                 if ( ! baz ) exit(EXIT_FAILURE);

>                 /* do stuff */
>         }

> The idea I have had expressed to me is that, given the program that calls
> foo() can't continue if foo() fails, one might as well have foo() terminate
> the program immediately upon fopen() failing.

> Personally, I think this is Bad(tm).  IMO, a function like foo() should
> return a failure condition, and the calling program should handle it
> gracefully.  *Especially* given that foo() is part of a shared library,
> intended for code reuse.

> Wotcha all think?

I agree 100%.  I would think that it is very Bad(tm) regardless, but
the fact that it's part of a library absolutely cinches it.

What if you'd like to print a helpful error message, or poll the user
for an alternate file name?  What if you'd like to employ a special
workaround, or perform some fancy diagnostics to try and determine why
the function failed?

It's pretty much never a good idea to exit() from a shared library
function, and in general program exits should be concentrated to as
small an area as possible (ideally, one - from main).

Micah



Sat, 24 Jul 2004 15:15:35 GMT  
 Returning error values vs. not returning

Quote:

> The idea I have had expressed to me is that, given the program that
> calls foo() can't continue if foo() fails, one might as well have
> foo() terminate the program immediately upon fopen() failing.

> Personally, I think this is Bad(tm).

I agree.  One reason has been mentioned: it removes your options as
to how you respond to the error.  Another reason that matters to me
is that I'd rather centralize my error handling somewhat, not have it
spread throughout the program.  This allows error handling to be a
bit more thoughtful/complex without duplicating code.

--

|_ http://www.Sonnack.com/ ___________________| Call: 1-800-DEV-NULL  |
|_____________________________________________|_______________________|

Opinions expressed herein are my own and may not represent those of my employer.



Sat, 24 Jul 2004 23:56:19 GMT  
 Returning error values vs. not returning


Quote:
> Fair enough.  But I'd still prefer:

>         int main(void)
>         {
>                 /* stuff */

>                 if ( ! foo(void) )
>                 {
>                         /* log stuff and display messages */
>                         exit(EXIT_FAILURE);
>                 }

>                 /* stuff */
>         }

Time to look at setjmp()/longjmp(). They can remove the need to pass error
return upon error return back up the call chain.

--
- Mark A. Odell
- Embedded Firmware Design, Inc.
- http://www.embeddedfw.com



Sun, 25 Jul 2004 00:45:27 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Not All Control Paths Return A Value/ Everything Is Not Valid

2. One return vs multiple returns

3. return an address VS return structure

4. return(x) vs return x

5. Method Output Parameter vs Return Value

6. Return Values vs. [out] params

7. TO RETURN OR NOT TO RETURN

8. Not all code paths return a value

9. function return value not correct.

10. Function not returning a correct value

11. atoll not returning value

12. not returning correct value

 

 
Powered by phpBB® Forum Software