C++ exception handling is defective

B

Bjoern Doebel

Grizlyk said:
Most OS _never_ will terminate process on overflow, or any recoverable
error, but OS _never_ can resume process. C language declare "signals"
as interdace between OS and C, but signals is too simple for C++. C++
must support better processing for the errors, as C++ support
exceptions instead of return error value.

No. Signals are declared by the POSIX standard and have nothing to do with
a certain programming language.


Bjoern
 
G

Gavin Deane

Grizlyk said:

Either you are still misunderstanding how to use the wrapper, or I am
completely misunderstanding you.

In the post you linked to above, you state:
<quote>
I am repeating again - source of the exception is hardware (CPU), the
test (rhs.data == 0) _is not enough_.
</quote>

The test (rhs.data == 0) as used in Kai-Uwe Bux's wrapper class is
entirely necessary and entirely sufficient to prevent divide by zero
ever happening. It doesn't make divide by zero a safe thing to do. It
make it impossible for divide by zero to happen.

rhs.data is the divisor in the division we are *considering* carrying
out. Note, *considering*. At the point of testing whether rhs.data ==
0, we have not decided whether to do the division or not. If it turns
out that rhs.data is zero, we decide not to attempt the division *at
all* because we know it will cause a problem. Instead, we throw an
exception (a C++ exception).

Clearly, if we were to try and divide by rhs.data, that would be
division by zero, which would be bad. But the precise point of the
wrapper class is that, in the case that rhs.data is zero, *no division
is carried out*. A completely different course of action, with well
defined behaviour, is taken.

Gavin Deane
 
I

Ian Collins

Bjoern said:
No. Signals are declared by the POSIX standard and have nothing to do with
a certain programming language.
Not so, signals are described (in rather vague language) in section
7.14.1 of the current C standard.
 
G

Gavin Deane

Grizlyk said:
If result of any operation is incorrect (overflow for example), in most
cases function will work with error. But in the case of "divide by
zero" all other perfectly working parts of program will be halted. It
will be much better if C++ will garantee, that program will not be halt
automaitcally on error like overflow.

Why is that better? In my opinion it is only good for the program to
continue if it's behaviour is defined. But you may disagree. If you do,
I'd be interested to hear why.

If you can come up with a means whereby C++ could offer the guarantee
you want, you are free to propose it to the standards committee. You
may find that comp.std.c++ is a good place to discuss your proposal. As
you develop your proposal, bear in mind two things:

1. Your proposal must imply zero overhead for programs that do not
require your guarantee. This is simply a fundamental design principle
of C++ that you cannot get away from.

2. A solution that guarantees well defined behaviour in an attempt to
divide by zero and also meets the requirement of my first point already
exists (use a wrapper class as suggested elsethread when you want the
protection, use built-in types directly when you don't). If you want
your proposal to be accepted, you should be prepared to explain how it
is superior to the solution that already exists.

Gavin Deane
 
I

Ian Collins

Grizlyk said:
Ian Collins wrote:




Most OS _never_ will terminate process on overflow, or any recoverable
error, but OS _never_ can resume process. C language declare "signals"
as interdace between OS and C, but signals is too simple for C++. C++
must support better processing for the errors, as C++ support
exceptions instead of return error value.
The C standard only describes the behaviour of signals generated by
raise(), anything else is left to the implementation.

As I've stated many times on this thread, how an underlying hardware
error is communicated to an application is determined by the operating
environment. If the environment uses asynchronous signals, these can't
be communicated to the applications running context without that context
continuously checking for them. It is the requirement that add an
unacceptable overhead.
Application can control.
OK, it may be able to control it, but at a huge cost.
 
G

Grizlyk

Ian said:
As I've stated many times on this thread, how an underlying hardware
error is communicated to an application is determined by the operating
environment. If the environment uses asynchronous signals, these can't
be communicated to the applications running context without that context
continuously checking for them. It is the requirement that add an
unacceptable overhead.

1. We must think about programmer, for the first.
It is wrong, if program will fall in the case of the stupid error as
divide_by_zero. C++ must not be oriented to CP/M and must expect
support of restore of recoverable errors from OS.

2.
I f the environment uses asynchronous signals,
these can't be communicated to the applications running context
without that context continuously checking for them.

Do not agree. Let use ix86.

There is group of really async events is INTR, NMI and so on.

But there is another large class of hardware generated exceptions,
which are really always synced to process excution. Among them INT,
INTO opcodes, "memory violations" and "divide by zero" "CPU
exceptions". Each of the "CPU exception" linked to concrete execution
point.

The error as "divide by zero" can not be async event, always, on ever
machine.

What can happend if error occured? For good OS, your process will
receive system depended event. C++ must convert system dependent event
into system independent - to signal or to exception. If any C++
environment will terminate process on the case of error - it is problem
of the OS, not C++.
It is the requirement that add an unacceptable overhead.
Write, what exactly will give overhead.
 
G

Grizlyk

Gavin said:
Why is that better? In my opinion it is only good for the program to
continue if it's behaviour is defined. But you may disagree. If you do,
I'd be interested to hear why.

What do you mean? Compare

//good
for(;;)
{
if(mouse) try{ aux_process(); }catch(...){ print("no mouse"); }
if(net) try{ net_process(); }catch(...){ print("no network"); }
//exit if only main process can not continue
try{ user_process(); }catch(...){ exit(); }
}

//ordinary exit at any point
for(;;)
{
try{
if(mouse) aux_process();
if(net) net_process();
user_process();
}catch(...){ exit(); }
}
 
G

Gavin Deane

Grizlyk said:
What do you mean? Compare

<snip>

I thought you were suggesting that, in the case of formally undefined
behaviour, you felt that for the program to continue with, by
definition, unpredicatable results would be prefereable to the program
halting. However, I don't see how your example code makes that point at
all so I probably misuderstood you.

Gavin Deane
 
G

Greymaus

Kai-Uwe Bux wrote:
if I regarded division by 0 a bug...


x/0 = infinity, where x equals any number. Why infinity? Because it
takes an infinite number of zeroes to equal any value.
[[gg]]

Conversely, the reciprocal of infinity is zero.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Grizlyk said:
It is wrong, if program will fall in the case of the stupid error as
divide_by_zero. C++ must not be oriented to CP/M and must expect
support of restore of recoverable errors from OS.

Just because you want?
 
G

Grizlyk

Gavin said:
I thought you were suggesting that, in the case of formally undefined
behaviour, you felt that for the program to continue with, by
definition, unpredicatable results would be prefereable to the program
halting. However, I don't see how your example code makes that point at
all so I probably misuderstood you.

The example of code shows, that on high level any error can be silently
ignored - or errored function will recalled or just passed, as in my
example.

The goal of C++ exception mechanism is dividing "source of exception"
from "exception handler". Code, what born divide_by_zero, often may not
decide exit or not exit, the code must post the error to his parent, to
up level.

If no more handler of up level exist - terminate or unexpected can be
called, else no sence to use exceptions.

In the sence, exception divide_by_zero is eqully to program generated
exception, it is evidently.
 
L

Lionel B

x/0 = infinity, where x equals any number.

We're talking about C++ here... what if the numerical type of x has no
representation of infinity? What if x is zero? What if x is negative? What
if x is NaN what if x is infinite? What if ...?

Ok, I presume you were trying to make the point that division by 0 need not
be considered a bug. Agreed - and so too, I'd guess, does Kai-Uwe, since he
said "*if* I regarded division by 0 a bug"...
Why infinity? Because it takes an infinite number of zeroes to equal
any value. [[gg]]
?

Conversely, the reciprocal of infinity is zero.

In some systems of arithmetic it might be considered so.
 
I

IR

Simon said:
But the (operating) system then has to handle those events and can
do so in a variety of ways. How the system handles them depends
on the system. And then, to take advantage of such event
handling, the language implementation has to do so in a way that's
compatible with the system's way of doing things. And then, when
it comes to the corresponding language-level exceptions, there may
well have to be the accompanying overheads just to answer the
question, "Has a system-level exception been thrown this time?"
So, even though such system-level exceptions wouldn't be thrown
most of the time, the overheads could still be there every single
time such a piece of code gets executed, just in case a
system-level exception does get thrown.

Indeed, I get your point. I guess my point of view was too Windows-
centric (as MS' SEH incurs no runtime cost as long as it is not
triggered).
I won't even mention our home-grown embedded devices based on 68HC16
microcontrollers, they are out of scope in this discussion although
they use a mechanism very similar to SEH.


Cheers,
 
G

Greymaus

Lionel said:
>
What if x is zero? What if x is negative? What
if x is NaN what if x is infinite? What if ...?
Any number divided by itself equals 1. (In the case of x=0 you have the
inconsistency of 0 being equal to 1.)
If x=infinity, it's also equal to 1, on the basis of being divided by
itself. IOW, infinity = 0, 1 and itself simultaneously, which is a BIG
inconsistency.

And all this time we've thought mathematics were LOGICAL...[[gg]]
 
P

peter koch

Greymaus skrev:
Lionel said:
What if x is zero? What if x is negative? What
if x is NaN what if x is infinite? What if ...?
Any number divided by itself equals 1. (In the case of x=0 you have the
inconsistency of 0 being equal to 1.)
If x=infinity, it's also equal to 1, on the basis of being divided by
itself. IOW, infinity = 0, 1 and itself simultaneously, which is a BIG
inconsistency.

And all this time we've thought mathematics were LOGICAL...[[gg]]

It is:
x**2 - x**2 = x**2 - x**2
<=> x(x - x) = (x+x)*(x-x)
<=> x = 2*x

This result should terminate all further discussion here ;-)

/Peter
 
G

Gavin Deane

Grizlyk said:
The goal of C++ exception mechanism is dividing "source of exception"
from "exception handler".

Correct, as long as you restrict yourself to the only applicable
definition of "exception". That is, the object thrown by a throw
statement in the C++ program.
Code, what born divide_by_zero, often may not
decide exit or not exit, the code must post the error to his parent, to
up level.
From the point of view of pure C++, where the definition of exception
that relates to your first sentence is applicable, there is no way of
knowing what code that tries to divide by zero will do. There is
certainly no reason to assume that a C++ exception will be thrown.
If no more handler of up level exist - terminate or unexpected can be
called, else no sence to use exceptions.

Divide by zero may cause terminate or unexpected to be called, or it
may not, in the same way that it may or may not invoke nasal demons.
One thing's for certain though. If you want to be able to predict what
will happen, the C++ language definition will not help you.
In the sence, exception divide_by_zero is eqully to program generated
exception, it is evidently.

What is evident?

When an exception (a C++ exception) is thrown, either a matching catch
block is found and that catch block is executed, or no matching catch
block is found and terminate is called. Guaranteed.

When divide by zero is encountered, anything might happen. Absolutely
no guarantees. The CPU might do something predictable by you, but not
predictable by the C++ language definition. The CPU might use the word
"exception" to describe what it does. There is no reason to equate what
the CPU does on divide by zero and what C++ does on a throw statement
just because both (completely unrelated) concepts happen to have the
same name.

The situations could not be more different. No equivalence whatsoever.

Gavin Deane
 
Z

Zorro

Greymaus said:
Kai-Uwe Bux wrote:
if I regarded division by 0 a bug...


x/0 = infinity, where x equals any number. Why infinity? Because it
takes an infinite number of zeroes to equal any value.
[[gg]]

Conversely, the reciprocal of infinity is zero.

Come on now. x cannot be 0. That would become undefined.
Regards.
 
Z

Zorro

peter said:
Greymaus skrev:
Lionel said:
x/0 = infinity, where x equals any number.


What if x is zero? What if x is negative? What
if x is NaN what if x is infinite? What if ...?
Any number divided by itself equals 1. (In the case of x=0 you have the
inconsistency of 0 being equal to 1.)
If x=infinity, it's also equal to 1, on the basis of being divided by
itself. IOW, infinity = 0, 1 and itself simultaneously, which is a BIG
inconsistency.

And all this time we've thought mathematics were LOGICAL...[[gg]]

It is:
x**2 - x**2 = x**2 - x**2
<=> x(x - x) = (x+x)*(x-x)
<=> x = 2*x

This result should terminate all further discussion here ;-)

/Peter

Yes, termination is in order as this is not going anywhere. On the
second line you are dividing by (x-x), which is 0. That is not a
permissible operation.

Regards.
 
D

David W

Greymaus said:
Kai-Uwe Bux wrote:
if I regarded division by 0 a bug...


x/0 = infinity, where x equals any number. Why infinity? Because it
takes an infinite number of zeroes to equal any value.

Not even an infinite number of zeroes will give you anything greater than zero.

DW
 

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

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top