Randall Parker <
XXXX@XXXXX.COM >writes:
Quote
Someone can write a stored proc in some sort of interpreted
language. But the interpreted language could get interpreted by C
code (I'm assuming that DB, MS SQL, etc are written in C/C++ and I
think this is true). Well, the interpreter could obviously test very
denominator before dividing. Or it could not do so and just have a
handler to handle the case.
In that situation, then, if the interpreter itself does a division by
zero, you may have undefined behavior due to the interpreter.
However, if the interpreter detects the problem itself and reports it
as a normal error in the language it defines, then quite likely it's
not a problem for your host application.
Quote
But if you write a handler that basically gives that event a defined
result it is no longer entirely undefined behavior.
In the case where undefined behavior occurs, there is no recovery,
period. You're writing your position from the perspective that "if
you handle it, it's ok", but that doesn't work. It's only ok if it
(undefined behavior) never happens in the first place.
Quote
If your compiler throws an exception when it hasppens it is not an
undefined behavior. It has a very defined behavior: throw an
exception.
That's not true. UNSPECIFIED behavior leaves the implementation
decision up to the compiler vendor. UNDEFINED behavior, however,
cannot ever have expected results. This is part of the definition of
the C++ language, and cannot be overridden by any vendor.
For example, on unix, when your program has performed an illegal
operation (for example, dereferencing a null pointer), you are given a
SIGSEGV signal, which is an indication that you're about to be
shutdown due to misbehavior. If you trap that signal and essentially
ignore it, that does not undo the damage that was done. Similarly,
when Windows sends an access violation to your program, it means "you
crashed". Catching it, like the VCL does, unfortuantely, does NOT mean
your program is safe to continue simply because you caught that
exception.
Quote
They understand that customer is king. I do what customers want me to
do. They want to not exit the program.
To satisfy their desires, it is necessary to write the program without
undefined behavior in the first place. Don't try to handle the
problem after it occurrs, because that cannot be done. Instead,
perform some checks BEFORE doing something that is potentially
invalid, and then don't do it if your tests detect that a problem
would occur. Division by zero, for example, is easy to detect before
it occurs, by inspecting the denominator prior to performing the
operation.
Quote
Look at Java. It has throwable exceptions as part of its
semantics. Exceptions in Java are considered normal. Too normal in
fact. There was a big debate on the JDOM list a few years back on
whether JDOM should throw exceptions when an element or an attribute
is not found. I argued against some big name people who wanted
exceptions to be thrown. Eventually (and fortunately) a more
restrictive use of exception throwing was decided upon.
You're confusing a normal runtime error with a program failure. A
real exception is thrown by the application's code. Undefined
behavior has unknown semantics, ranging from doing nothing noticeable
at all (though possibly still with severe corruption), to receiving a
signal/"structured exception" from the OS. But in neither case is an
exception (in the C++ sense of the word) actually thrown. That the
VCL translates structured exceptions into VCL exceptions is, IMHO, a
grave disservice to their customers who don't understand the issues.
Quote
Mind you, I do not like Java exceptions. But I do not think it makes
sense to equate an undefined behavior with throwing an
exception.
I do not equate them at all. I'm saying that if you can detect
"undefined behavior", throwing an exception does not sufficiently
"handle" the problem.
Quote
Seems to me that unless the condition causes unpredictable
side effects why not handle it if you can and keep on going? Why not
just make the behavior defined if the engineering trade-off seems
worth it?
You won't like this answer, because it is pedantic, but because the
definition of the language clearly states that there are no
requirements on a program after undefined behavior occurs, there are
no requirements on a program after undefined behavior occurs. That
simply is how C++ works.
Quote
Say a dereference of a bad pointer causes an exception.
No, it does not cause an exception. The *only* way for an exception
to be caused is to write C++ code that evaluates a "throw"
expression.
Quote
The bad pointer has to be recognized as bad in order to throw the
exception in the first place.
And if it's not recognized, then silently your program writes into
memory that it shouldn't, and you have a corrupted runtime
environment. Buffer overrun, anyone?
Quote
Suppose it is recognized as bad because it the program tries to
write to a location that is write protetcted. Well, it did not
corrupt anything by doing so since an exception happened instead of
the write.
Once you perform undefined behavior you cannot expect any reasonable
behavior afterwords, unless perhaps, in some environment the compiler
did clearly define what happens. However, the majority of cases do
not have such documentation from compiler vendors, and certainly, an
OS signal is not a C++ exception, and it's wrong to confuse the two.
Quote
You could claim that the bad pointer is an indication that some bug
exists that might have caused other bad things to happen. True
enough.
Ok, we are in agreement here.
Quote
But, first of all, all programs have bugs.
This does not excuse them. And no, not all programs have bugs like
that. Some bugs are simply missing features, or logic bugs that
perform the wrong calculation. However, memory-corruption bugs are
*never* something we can just accept.
Quote
Some happen routinely. For example, BCB gives me exceptions
sometimes when I compile.
I often have to Build All to get around the exceptions. I do not
want BCB to automatically exit when it hits an internal exception.
www.datanation.com/fallacies/conseq.htm
Quote
Some types of exceptions are used by operating systems routinely as
essential to how the operating system. functions. For example, trying
to read a memory loc that is paged out of virtual memory? The
exception handler brings the data in from a swap file.
You're confusing "structured exceptions" with C++ exceptions. The two
are completely seperate, unrelated ideas.
--
Chris (TeamB);