reporting programming error

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

    reporting programming error

    Greetings,

    Is there a consensus as to the best way to report a programming error, for
    example an out of bounds index value passed to a function? There are three
    approaches that I can think of:

    [1] (traditional) error return value
    [2] error value in object
    [2] exception

    Below are examples of how they might be used by functions that check their
    index parameter for for out of bounds.

    // [1]
    er = object.process_ index(index);
    assert(er == 0);

    // [2]
    object.process_ index(index);
    assert(object.e rror == 0);

    // [3]
    try { object.process_ index(index); }
    catch(...) { assert(false); }

    Programming errors are, I assume, most likely found via asserts. If this is
    the case, the cleanest approach seems to be approach [2]. This prevents
    cluttering up the call with error types and limits those references to the
    assert.

    Thanks


  • Jeff Schwab

    #2
    Re: reporting programming error

    Ian Lazarus wrote:[color=blue]
    > Greetings,
    >
    > Is there a consensus as to the best way to report a programming error, for
    > example an out of bounds index value passed to a function? There are three
    > approaches that I can think of:
    >
    > [1] (traditional) error return value
    > [2] error value in object
    > [2] exception[/color]

    I for one like exceptions in this case. If the caller of my function
    can't even use it as directed, I certainly don't trust said caller to
    check for an error value. I'd just as soon pass error information back
    as far as necessary to find a more responsible layer of the program.

    Comment

    • E. Robert Tisdale

      #3
      Re: reporting programming error

      Ian Lazarus wrote:
      [color=blue]
      > Is there a consensus as to the best way to report a programming error?
      > For example an out of bounds index value passed to a function?
      > There are three approaches that I can think of:
      >
      > [1] (traditional) error return value
      > [2] error value in object
      > [3] exception
      >
      > Below are examples of how they might be used by functions
      > that check their index parameter for for out of bounds.
      >
      > // [1]
      > er = object.process_ index(index);
      > assert(er == 0);
      >
      > // [2]
      > object.process_ index(index);
      > assert(object.e rror == 0);
      >
      > // [3]
      > try { object.process_ index(index); }
      > catch(...) { assert(false); }
      >
      > Programming errors are, I assume, most likely found via asserts.
      > If this is the case, the cleanest approach seems to be approach [2].
      > This prevents cluttering up the call with error types
      > and limits those references to the assert.[/color]

      #include <iostream>

      class myClass {
      private:
      int max_index;
      public:
      myClass& process_index(i nt index, const char* file, int line);
      myClass& process_index(i nt index);
      };

      myClass& myClass::proces s_index(int index,
      const char* file, int line) {
      if (index < 0 || max_index < index)
      std::cerr << "Index out of bounds "
      << "in function myClass::proces s_index(int) "
      << "at line #" << line
      << " in file " << file << std::endl;
      return process_index(i ndex);
      }

      #ifndef NDEBUG
      #define process_index(i ndex) \
      process_index(( index), __FILE__, __LINE__)
      #endif//NDEBUG

      Comment

      • Claudio Puviani

        #4
        Re: reporting programming error

        "Ian Lazarus" <nobody@nowhere .net> wrote[color=blue]
        > Is there a consensus as to the best way to report a programming
        > error, for example an out of bounds index value passed to a
        > function?[/color]

        There's definitely no consensus on the best way, but there is consensus on
        various wrong ways.
        [color=blue]
        > There are three approaches that I can think of:
        >
        > [1] (traditional) error return value
        > [2] error value in object
        > [2] exception
        >
        > Below are examples of how they might be used by functions that check their
        > index parameter for for out of bounds.
        >
        > // [1]
        > er = object.process_ index(index);
        > assert(er == 0);[/color]

        This is the old-style C way of handling errors. The advantages are that it's
        simple and it allows a programmer to ignore the error. The disadvantage is that
        it allows the programmer to ignore the error.
        [color=blue]
        > // [2]
        > object.process_ index(index);
        > assert(object.e rror == 0);[/color]

        Except under rare conditions, this is an all-around bad approach. The exception
        applies to those objects whose internal state actually does change due to an
        error, such as streams, sockets, files, etc. and where the object can no longer
        be used until the condition is rectified. In practically all other cases, it's a
        design error that associates the exit state of the operation with the static
        state of the object. The only place one should be interested in the last error is
        where the error occurred. Let's not even get into the mess that this approach can
        cause in multi-threaded programs.
        [color=blue]
        > // [3]
        > try { object.process_ index(index); }
        > catch(...) { assert(false); }[/color]

        This is the "standard" C++ way of handling errors. However, it has one major
        disadvantage: the caller can't ignore the error. Of course, the advantage is that
        the caller can't ignore the error. :-)
        [color=blue]
        > Programming errors are, I assume, most likely found via asserts.[/color]

        The case for 'assert' is fuzzier. Many people object to asserts on a variety of
        grounds, the most often voiced being that the non-debug code will be different
        from the debug version and any inadvertent side-effects introduced in the asserts
        will be missing from the non-debug code. Others feel that better error-handling
        (standardized logging, etc.) should be used instead. Personally, I like liberally
        sprinkling asserts in my code, but you shouldn't assume that it's a universal
        sentiment.
        [color=blue]
        > If this is the case, the cleanest approach seems to be approach [2].
        > This prevents cluttering up the call with error types and limits those
        > references to the assert.[/color]

        while (true) {
        std::cerr << "NO!!!" << std::endl;
        }

        [1] and [3] are acceptable (for the record, I prefer [3]). [2] is simply
        unacceptable unless the error really is part of the object's natural state.

        Claudio Puviani


        Comment

        • Benoit Mathieu

          #5
          Re: reporting programming error

          > Programming errors are, I assume, most likely found via asserts. If this is[color=blue]
          > the case, the cleanest approach seems to be approach [2]. This prevents
          > cluttering up the call with error types and limits those references to the
          > assert.[/color]

          If your software is interactive and it's difficult to run it
          twice with the same input (word processor, gui, ...), or if
          program execution should never stop (monitoring system,
          ....), I think that the programmer should assume that there
          are bugs, i.e. not rely on assert, handle errors in a clean
          way (I don't like to loose data because the application
          crashed due to an internal error) and output as much
          information as possible to enable debugging without running
          the program again because you might be unable to reproduce
          the problem. The program should behave as if that particular
          feature where the bug happened is missing.

          Comment

          Working...