reporting programming error

I

Ian Lazarus

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.error == 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
 
J

Jeff Schwab

Ian said:
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

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.
 
E

E. Robert Tisdale

Ian said:
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.error == 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.

#include <iostream>

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

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

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

Claudio Puviani

Ian Lazarus said:
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's definitely no consensus on the best way, but there is consensus on
various wrong ways.
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);

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.
// [2]
object.process_index(index);
assert(object.error == 0);

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.
// [3]
try { object.process_index(index); }
catch(...) { assert(false); }

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. :)
Programming errors are, I assume, most likely found via asserts.

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.
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.

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
 
B

Benoit Mathieu

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.

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top