Re: Error codes vs. exceptions
IMO&IME obsession with logging normally lurks in rotten projects, and is
player in the rot. Efforts could be put to write correct code instead,
kind that is light, focused, readable.
Efforts has to be put first and utmost to satisfying the customer. Logging
is a user (and sometimes, regulatory, too) requirement, not a design
decision left up to the software engineer.
Logging return codes of library calls and content of exceptions?
I seriously doubt any kind of regulation would deal with that. I'm skeptic
about customer too.
Real logging is indeed often a requirement, but it's a completely different
beast -- you write a log of action taken by the program, changes of
database, etc. It goes on much higher level.
The fragments we dscussed here, that ask actions in error handling branches
close to call places is more like TRACE, and if ever looked after, serves to
find problems with the program implementation.
Also, correctness of the code has little to do with the necessity of the
logging: the error logging is mainly for the error conditions caused by
input data and computational environment (broken connections, corrupted or
full disk drives etc).
And those fit pretty well at the top level actions, and need not do anything
but write out exception.what() with a timestamp.
I.e. all you want to see in log is "OS error #??? 'disk full' on savig file
'/etc/bar'". no interest in which byte failed in which
But if you need something like that I still don't see why is it that
create a simple RAII class that you put as local at every function entry,
its OK() at the exit. In case of unexpected exit it emits a log line from
Why would you complicate and pessimize the main code path of the program?
I didn't say you should, only that it can be done if requirement emerges --
possibly just as a drop-in to corner a problem detected by a test. And the
point is that it can be done *without* messing up the code path and create
visible conditional or try blocks.
If error is not created 99.999% of the times, why would I make my user to
create, pass and destroy that object on every function call? (It will also
have to check the error condition; but that has to be done with error
codes, too, so I did not count it as pessimization).
As the state of the object is just a bool maximum an int, so I'm sure you
could not measure its presense in a real application. (On PCs the
performance is determimned by memory cache unless you stall or something
even slower... current processors stall 50-100 ticks on any cache miss. ALU
operations come practically free. )
You can simply add checkpointing or insert info on actions you will do. I
i could write a simple macro to automate most of the magic. Leaving way
clutter than the retcodes version.
How the version with return code whose processing is wrapped in macros
will leave more cluter than RAII version of the same?
Just write the code and look at it. Unless you can show me a return code
processing without a sigle IF or condition.
It is instructive that in some libraries designed for critical
serious ISPs (e.g. IBM's MQ Series C API), the error codes were returned
That sounds weird. Can you explain why is that good? With the usual way I
make the functions CHECKRETURN and use the compiler to flag places where
was ignored, without extra effort. I'm not aware of similar support on
arguments used for output.
A programmer using such API does not have a chance to fully ignore error
conditions because s/he needs to define a variable (sometimes more than
to hold error codes.
With a C API? how hard it is to pass NULL for the output param? And even
force to pass a variable what makes the code look at it more than the
Hey, we are not talking about *willingly* shooting yourself in a leg. What
I mean is that the programmer will have to type in that NULL (actually in
C++ it is rather 0 or that nullptr beast). If s/he does not know or think
why s/he is typing stuff, there is no technical solution to this problem.
You evaded the question. The checkreturn attribute flags exactly what it
suposed to: an accidental overlook. How an out param wants to be better?
Programmers are, in general, not dumb, but they are people and they forget
things and they are sometimes somewhat sloppy. It is forgetfulness and
sloppiness that is responsible for not checking those error codes or not
catching those exceptions. A timely reminder helps a forgetful programmer
and can sometimes control light forms of sloppiness.
I agree with that, that's why I don't get the point of this "improvement".
You turn on the checkreturn warning and add /Werror (that we normally use
unless have some very hostile unkillable warnings), and presto -- failing
build is quite a reminder for the forgetful, isn't it?