Error handling in C

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • arnuld

    #1

    Error handling in C

    Can anyone point me to some online/offline document on error handling in C
    ?

    I am doing some Socket Programming in C and feeling a lots of difficult in
    error handling :(

    Also some time ago some one told me that when I get an error then I can
    create a generic function which, when called within some function will
    print the name of that function automatically or something like that I
    forgot. It had lots of #define(s) . Can someone write that for me ?



    --

    my email is @ the above blog.


  • Eric Sosman

    #2
    Re: Error handling in C

    arnuld wrote:
    Can anyone point me to some online/offline document on error handling in C
    ?
    >
    I am doing some Socket Programming in C and feeling a lots of difficult in
    error handling :(
    If there's a good document on the topic, I haven't seen it.
    But I'll offer a few thoughts; take 'em or leave 'em.

    There are two aspects to error handling: Detection of the
    error condition and response to it. The first is dictated by
    the API you're using: A function is documented to return NULL
    or to set a global variable to 0xBaddBadd or whatever, and it's
    up to you as the function's caller to make the indicated test.
    If you're writing your own functions and want to report errors
    from them, you can choose whatever means you like; consider the
    other existing functions you use and imitate the style of those
    you find easiest to get along with.

    Once the error is detected, the response is a much thornier
    problem. It has more to do with the structure of your program
    and with the way the program is used than with the error itself.
    Often, you want to get back to a "neutral state" where a user
    can try the operation again, or try a different operation. But
    for some programs there may be no "user:" a program that runs
    unattended can't very well ask Higher Authority what to do if
    something goes wrong. This is an area of great difficulty.

    Some languages provide frameworks that favor a particular
    style of error handling, things like "exceptions " in C++ or
    Java, for example. C doesn't offer much of this sort of thing,
    which is sometimes a curse and sometimes a blessing.
    Also some time ago some one told me that when I get an error then I can
    create a generic function which, when called within some function will
    print the name of that function automatically or something like that I
    forgot. It had lots of #define(s) . Can someone write that for me ?
    If you can write specifications this clearly and precisely,
    you'll have a brilliant and successful career -- in management.

    --
    Eric Sosman
    esosman@ieee-dot-org.invalid

    Comment

    • Nick Keighley

      #3
      Re: Error handling in C

      On 19 Nov, 13:11, arnuld <sunr...@invali d.addresswrote:
      Can anyone point me to some online/offline document on error handling in C?
      I've never seen a good one. Doesn't mean there isn't one, just I've
      never seen it.
      I am doing some Socket Programming in C and feeling a lots of difficult in
      error handling :(
      yeah, error handling in C can be a pain. Especially if you've used
      something with exceptions.

      You might end up with something like this:-

      <code>
      int activesock (const char *host, int port, const char *protocol)
      {
      struct hostent *phe;
      struct servent *pse;
      struct protoent *ppe;
      struct sockaddr_in sin;
      int s, type;

      memset (&sin, 0, sizeof sin);

      sin.sin_family =AF_INET;
      sin.sin_port = htons (port);

      /* map host name to ip addr allowing for dotted decimal */
      if ((phe = gethostbyname (host)))
      memcpy (&sin.sin_add r, phe->h_addr, phe->h_length);
      else
      if ((sin.sin_addr. s_addr = inet_addr (host)) == INADDR_NONE)
      raise_report (LEVEL_FATAL, "activesock ", "can't get \"%s\"
      host entry\n", host);

      /* map protocol name to protocol number */
      if ((ppe = getprotobyname (protocol)) == 0)
      raise_report (LEVEL_FATAL, "activesock ", "can't get \"%s\"
      protocol entry\n", protocol);

      /* use protoicol to choose socket type */
      if (strcmp (protocol, "udp") == 0)
      type = SOCK_DGRAM;
      else
      type = SOCK_STREAM;

      /* allocate a socket */
      /* s = socket (PF_INET, type, ppe->p_proto); */
      s = socket (PF_INET, type, DEFAULT_PROTOCO L);
      if (s < 0)
      raise_report (LEVEL_FATAL, "activesock ", "can't create socket:
      %s\n", strerror (errno));

      /* connect to the socket */
      if (connect (s, (struct sockaddr *)&sin, sizeof sin) < 0)
      raise_report (LEVEL_FATAL, "activesock ", "can't connect to %s.
      %d: %s\n", host, port, strerror (errno));

      return s;
      }
      </code>


      basically you have to check the return value of every function.
      But then that's good for you. Much as eating your vegetables and
      drinking 2 pts of water is good for you.

      In the above raise_report() writes to a log file and possibly
      terminates the program.

      A language with exceptions can look much nicer

      <code>
      DEFAULT_PROTOCO L = 0

      sock = socket.socket (socket.AF_INET , socket.SOCK_STR EAM,
      DEFAULT_PROTOCO L)

      if len (sys.argv) < 2 :
      host = "localhost"
      else:
      host = sys.argv [1]

      sock.connect ((host, 8702))
      </code>

      But, of course, exceptions have their own pitfalls.

      Also some time ago some one told me that when I get an error then I can
      create a generic function which, when called within some function will
      print the name of that function automatically or something like that I
      forgot. It had lots of #define(s) . Can someone write that for me ?
      I don't think you can do this in C89. C99 has something like
      __function__()
      (I can't rememeber the exact spelling). My report routine above
      takes a parameter for the function name. To be honest __FILE__ and
      __LINE__ are usually good enough for me. Ok you don't want the user
      to
      see file and line, but then you don't want him to see function either.

      One trick is to have your functions return an error value.

      Rv do_big_thing()
      {
      do_sub_thing1() ;
      do_sub_thing_2( );
      return OK;
      }

      this can be nested

      Rv do_big_thing()
      {
      if ((rv = do_sub_thing1() ) != OK)
      {
      log_error();
      return rv;
      }

      if ((rv = do_sub_thing_2( )) != OK)
      {
      log_error();
      return rv;
      }

      return OK;
      }

      with suitable macro trickery this reduces to

      Rv do_big_thing()
      {
      CHECK_CALL (do_sub_thing1( ));
      CHECK_CALL (do_sub_thing_2 ());
      return OK;
      }

      of course I now have a nasty macro, a global variable and a function
      with multiple exits.

      The price of greenspunning

      --
      Nick Keighley

      why isn't there an obfuscated C++ contest?

      Comment

      • James Kuyper

        #4
        Re: Error handling in C

        arnuld wrote:
        ....
        Also some time ago some one told me that when I get an error then I can
        create a generic function which, when called within some function will
        print the name of that function automatically or something like that I
        forgot. It had lots of #define(s) . Can someone write that for me ?
        In C99 you can use the pre-defined identifier __func__. When used, it
        behaves exactly as if the following declaration had been inserted
        immediately after the '{' at the start of the enclosing function:

        static const char __func__[] = "function-name";

        This feature was not available in C89, and I know of no way to do what
        you're asking for without making use of __func__.

        Comment

        • Joachim Schmitz

          #5
          Re: Error handling in C

          Nick Keighley wrote:
          On 19 Nov, 13:11, arnuld <sunr...@invali d.addresswrote:
          <snip>
          >Also some time ago some one told me that when I get an error then I
          >can create a generic function which, when called within some
          >function will print the name of that function automatically or
          >something like that I forgot. It had lots of #define(s) . Can
          >someone write that for me ?
          >
          I don't think you can do this in C89. C99 has something like
          __function__()
          (I can't rememeber the exact spelling).
          __func__ and it's a string, not a macro (and not a function like macro
          either)

          I once had a hard time searching for in in the standard. Searching for
          _func_ works and finds
          _ _func_ _ (with a small space bewteen the _)

          bye, Jojo


          Comment

          • Ben Bacarisse

            #6
            Re: Error handling in C

            arnuld <sunrise@invali d.addresswrites :
            Can anyone point me to some online/offline document on error handling in C
            ?
            I am not aware of one, sorry.
            I am doing some Socket Programming in C and feeling a lots of difficult in
            error handling :(
            A common error I used to see in people starting out is to write the
            program as if all is well and then, later, try to put the error
            handling in. This does not work in C. You have to design the program
            to handle all the failures you care about from the start. If you
            haven't done this then, no matter how painful it may seem, you will
            probably be better off starting over (you will be able to re-use bits
            you've written so it is only the design you must re-do).

            Most things work only one way but can fail in numerous ways. This
            means there is often more code to handle errors than anything else.
            If your algorithms are reasonably complex there may be a fair balance,
            but a server that does something quite simple will be mostly error
            handling code!
            Also some time ago some one told me that when I get an error then I can
            create a generic function which, when called within some function will
            print the name of that function automatically or something like that I
            forgot. It had lots of #define(s) . Can someone write that for me ?
            Do you mean something that simply reports errors? If so a starting
            point might be (uses C99):

            #define REPORT(...) do { \
            fprintf(stderr, "In %s(): ", __func__); \
            fprintf(stderr, __VA_ARGS__); \
            fputc('\n', stderr); \
            } while (0)

            though I'd be inclined to turn this into a function with a simpler macro
            as a wrapper.

            --
            Ben.

            Comment

            • dj3vande@csclub.uwaterloo.ca.invalid

              #7
              Re: Error handling in C

              In article <gg14jr$e9o$1@n ews.motzarella. org>,
              Eric Sosman <esosman@ieee-dot-org.invalidwrot e:
              C doesn't offer much of this sort of thing,
              >which is sometimes a curse and sometimes a blessing.
              That one sentence, presented without context, makes an excellent
              summary of pretty much everything that people love and hate about C.


              dave

              --
              Dave Vandervies dj3vande at eskimo dot com
              No-one has a fully functional brain; brains have mutable (and
              mutated) state.
              --Chris Dollin in comp.lang.c

              Comment

              • Martin Ambuhl

                #8
                Re: Error handling in C

                arnuld wrote:
                Can anyone point me to some online/offline document on error handling in C
                ?
                >
                I am doing some Socket Programming in C and feeling a lots of difficult in
                error handling :(
                >
                Also some time ago some one told me that when I get an error then I can
                create a generic function which, when called within some function will
                print the name of that function automatically or something like that I
                forgot. It had lots of #define(s) . Can someone write that for me ?
                If you have a C99 implementation, the function name is the predefined
                identifier __func__ which follows block scoping rules. Your code needs
                nothing long or involved:

                /* C99 example */
                #include <stdio.h>

                void whoami(void)
                {
                fprintf(stderr, "Function %s does almost nothing\n". __func__);
                }

                Many pre-C99 implementations provide a similar mechanism, but this will
                often be a macro (__func__ behaves as if it were a block-scope pointer
                to static const char[].). For example, if you use GCC 3.4 or later, its
                special name __FUNCTION__ behaves like __func__, but for GCC 3.3 or
                earlier __FUNCTION__ behaved like a string constant, just as __FILE__,
                __DATE__, and __TIME__ were and still are string constants. In
                implementations for which the functionality of the C99 __func__ is
                approximated with a macro expanding to a string constant, the above
                approach still works:

                /* example of one non-standard C89 extension, where the predefined
                macro __FUNCTION__ expands to a string constant */
                #include <stdio.h>

                void whoami(void)
                {
                fprintf(stderr, "Function %s does almost nothing\n".
                __FUNCTION__);
                }

                There are other ways to use macros that expand to string constants which
                are not available when using __func__, but for just that reason they
                should be avoided. But here is an example that should continue to work:

                #include <stdio.h>
                #if !defined(__FUNC TION__)
                #if defined(__STDC_ VERSION__) && (__STDC_VERSION __ >= 199901L)
                #define __FUNCTION__ __func__
                #else
                #define __FUNCTION__ "<unknown>"
                #endif
                #endif


                void whoami(void)
                {
                fprintf(stderr, "At line %d in " __FILE__ "\n"
                "Translated at " __TIME__ "on " __DATE__ "\n"
                "In function %s\n."
                __LINE__, __FUNCTION__);
                }

                Comment

                • s0suk3@gmail.com

                  #9
                  Re: Error handling in C

                  On Nov 19, 8:33 am, Eric Sosman <esosman@ieee-dot-org.invalidwrot e:
                       Some languages provide frameworks that favor a particular
                  style of error handling, things like "exceptions " in C++ or
                  Java, for example.  C doesn't offer much of this sort of thing,
                  which is sometimes a curse and sometimes a blessing.
                  C doesn't provide those, but there are frameworks, such as:
                  http://home.rochester.rr.com/bigbyofrocny/GEF/

                  Sebastian

                  Comment

                  • CBFalconer

                    #10
                    Re: Error handling in C

                    arnuld wrote:
                    >
                    Can anyone point me to some online/offline document on error
                    handling in C ?
                    >
                    I am doing some Socket Programming in C and feeling a lots of
                    difficult in error handling :(
                    Sockets are not part of standard C, and are thus off-topic in
                    c.l.c. You can reference the standard in the following:

                    Some useful references about C:
                    <http://www.ungerhu.com/jxh/clc.welcome.txt >
                    <http://c-faq.com/ (C-faq)
                    <http://benpfaff.org/writings/clc/off-topic.html>
                    <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf(C99)
                    <http://cbfalconer.home .att.net/download/n869_txt.bz2 (pre-C99)
                    <http://www.dinkumware. com/c99.aspx (C-library}
                    <http://gcc.gnu.org/onlinedocs/ (GNU docs)
                    <http://clc-wiki.net/wiki/C_community:com p.lang.c:Introd uction>
                    >
                    Also some time ago some one told me that when I get an error then
                    I can create a generic function which, when called within some
                    function will print the name of that function automatically or
                    something like that I forgot. It had lots of #define(s) . Can
                    someone write that for me ?
                    No, but here is all you need, from the standard (needs C99):

                    6.4.2.2 Predefined identifiers

                    Semantics

                    [#1] The identifier __func__ shall be implicitly declared by
                    the translator as if, immediately following the opening
                    brace of each function definition, the declaration

                    static const char __func__[] = "function-name";

                    appeared, where function-name is the name of the lexically-
                    enclosing function.53)

                    --
                    [mail]: Chuck F (cbfalconer at maineline dot net)
                    [page]: <http://cbfalconer.home .att.net>
                    Try the download section.

                    Comment

                    Working...