Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C++ exception handling is defective

5 views
Skip to first unread message

Zorro

unread,
Jan 9, 2007, 5:55:19 PM1/9/07
to
The simplicity of stack unraveling of C++ is not without defective
consequences. The following article points to C++ examples showing the
defects. An engineer aware of defects can avoid hard-to-find bugs.

http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defective.html

Regards,
zor...@ZHMicro.com
http://www.zhmicro.com
http://distributed-software.blogspot.com
http://groups-beta.google.com/group/computerlangZ?lnk=la&hl=en

Rolf Magnus

unread,
Jan 9, 2007, 6:08:30 PM1/9/07
to
Zorro wrote:

> The simplicity of stack unraveling of C++ is not without defective
> consequences. The following article points to C++ examples showing the
> defects. An engineer aware of defects can avoid hard-to-find bugs.
>
>
http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defective.html

None of the C++ examples in the PDF linked from there is actually using
exception handling. They all invoke undefined behavior. They don't show a
defect in C++'s exception handling, but rather a lack of the author's
understanding of C++.

BTW: Those examples are also using the <iostream.h> header that has been
outdated in C++ for about 10 years now and has actually never even been
part of the C++ Standard.

Ian Collins

unread,
Jan 9, 2007, 6:31:55 PM1/9/07
to
Rolf Magnus wrote:
> Zorro wrote:
>
>
>>The simplicity of stack unraveling of C++ is not without defective
>>consequences. The following article points to C++ examples showing the
>>defects. An engineer aware of defects can avoid hard-to-find bugs.
>>
>>
>
> http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defective.html
>
> None of the C++ examples in the PDF linked from there is actually using
> exception handling. They all invoke undefined behavior. They don't show a
> defect in C++'s exception handling, but rather a lack of the author's
> understanding of C++.
>
Agreed, I wonder which compiler and environment produced the results
claimed.

> BTW: Those examples are also using the <iostream.h> header that has been
> outdated in C++ for about 10 years now and has actually never even been
> part of the C++ Standard.
>

Not to mention idiomatic C (void).

--
Ian Collins.

David W

unread,
Jan 9, 2007, 6:48:22 PM1/9/07
to
"Zorro" <zor...@comcast.net> wrote in message
news:1168383319.1...@o58g2000hsb.googlegroups.com...

> The simplicity of stack unraveling of C++ is not without defective
> consequences. The following article points to C++ examples showing the
> defects. An engineer aware of defects can avoid hard-to-find bugs.
>
>
http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defecti
ve.html

The fact that the code samples use <iostream.h> and not <iostream> suggests that
a very old compiler was used to demonstrate the supposed exception bugs. If the
code is updated for <iostream> and the divisions by zero are replaced by throws
(/0 causes undefined behaviour) and a more recent compiler is used, I think
you'll find that the destructor is indeed called when the stack is unwound. It
looks like a defective compiler rather than a defective language.

DW


Julián Albo

unread,
Jan 9, 2007, 7:20:21 PM1/9/07
to
David W wrote:

> The fact that the code samples use <iostream.h> and not <iostream>
> suggests that a very old compiler was used to demonstrate the supposed
> exception bugs. If the code is updated for <iostream> and the divisions by
> zero are replaced by throws (/0 causes undefined behaviour) and a more
> recent compiler is used, I think you'll find that the destructor is indeed

Better say a correct compiler. I have seen Borland Kilyx failing to call
destructors in cases similar to that (but correct). I even asked here if
the code has some error I failed to see, if I remember well. And Borland
acknowledged the bug, but failed to provide a solution (at least during the
time that I have the patience to keep checking).

--
Salu2

Zorro

unread,
Jan 10, 2007, 12:39:54 AM1/10/07
to

This is a common reply to several comments, respectfully.

1. The use of one or another header file is cosmetic for this example.
2. When you say a correct compiler will do better, please specify the
compiler.
3. Division by 0 happens at system level and is not necessary to turn
it into a throw.
4. For this example, the compiler is Microsoft Visual C++ version 6.
5. The defect is in the technique used. Of course it can be corrected.
Show me a compiler that has in fact corrected this problem. The point
is that, it takes a great deal beyond plain stack unraveling to correct
this problem.
6. If you are not familiar with the concept, and do not see the real
issue, avoid revealing it.

With respect, the best way I could present my response.

Ian Collins

unread,
Jan 10, 2007, 1:02:10 AM1/10/07
to
Zorro wrote:
> Zorro wrote:
>
>>The simplicity of stack unraveling of C++ is not without defective
>>consequences. The following article points to C++ examples showing the
>>defects. An engineer aware of defects can avoid hard-to-find bugs.
>>
>>http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defective.html
>>
>>Regards,
>>zor...@ZHMicro.com
>>http://www.zhmicro.com
>>http://distributed-software.blogspot.com
>>http://groups-beta.google.com/group/computerlangZ?lnk=la&hl=en
>
>
> This is a common reply to several comments, respectfully.
>
> 1. The use of one or another header file is cosmetic for this example.

It may or may not be cosmetic, but is asking for flak.

> 2. When you say a correct compiler will do better, please specify the
> compiler.

Changing you example to standard C++:

#include <iostream>

struct simple
{
int s;
simple() { s = 5;}
~simple(void) {std::cout << "Destructor ..." << std::endl;}
};

int main(){
int i = 1, j = 0;
try {
simple spl;
throw 0;
}
catch(...) {
std::cout << "Caught it" << std::endl;
}
std::cout << "Finishing" << std::endl;
return 0;
}

any compiler should give the correct result. If not, it is broken.

> 3. Division by 0 happens at system level and is not necessary to turn
> it into a throw.

Then why use it in your examples?

> 4. For this example, the compiler is Microsoft Visual C++ version 6.

Old and not very compliant.

> 5. The defect is in the technique used. Of course it can be corrected.
> Show me a compiler that has in fact corrected this problem. The point
> is that, it takes a great deal beyond plain stack unraveling to correct
> this problem.

Show me one that exibits it.

> 6. If you are not familiar with the concept, and do not see the real
> issue, avoid revealing it.
>

Which concept?

--
Ian Collins.

Kai-Uwe Bux

unread,
Jan 10, 2007, 1:02:37 AM1/10/07
to
Zorro wrote:

>
> Zorro wrote:
>> The simplicity of stack unraveling of C++ is not without defective
>> consequences. The following article points to C++ examples showing the
>> defects. An engineer aware of defects can avoid hard-to-find bugs.
>>
>>
http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defective.html
>>
>> Regards,
>> zor...@ZHMicro.com
>> http://www.zhmicro.com
>> http://distributed-software.blogspot.com
>> http://groups-beta.google.com/group/computerlangZ?lnk=la&hl=en
>
> This is a common reply to several comments, respectfully.
>
> 1. The use of one or another header file is cosmetic for this example.
> 2. When you say a correct compiler will do better, please specify the
> compiler.

Your compiler did just fine. The output you present is a perfectly valid
output for the program.

> 3. Division by 0 happens at system level and is not necessary to turn
> it into a throw.

The problem with the division by 0 is that it simply is undefined behavior
according to the standard. The language specification places no
requirements upon the observable behavior of any program that executed a
division by 0. Therefore, the output you attribute to incorrect handling of
exceptions is a perfectly valid output for your program (and so would be
any other).

What puts your program into an inconsistent state is not some exception but
the division by 0, which is UB.

> 4. For this example, the compiler is Microsoft Visual C++ version 6.
> 5. The defect is in the technique used. Of course it can be corrected.

The defect lies in the undefined behavior.

> Show me a compiler that has in fact corrected this problem. The point
> is that, it takes a great deal beyond plain stack unraveling to correct
> this problem.

Your program does not illustrate problem with stack unravelling. It
illustrates that all bets are off once you have undefined behavior.

> 6. If you are not familiar with the concept, and do not see the real
> issue, avoid revealing it.

Huh?


Best

Kai-Uwe Bux

Zorro

unread,
Jan 10, 2007, 1:31:06 AM1/10/07
to

Kai-Uwe, division by 0 is undefined just as trying to deref a null
pointer. These are exceptional cases that can happen. Simply calling
them (undefined behavior) does not help in anyway. Are you saying that,
if one of these cases, or many similar ones, happens the program should
necessarily terminate? Then what is the point of having an exception
mechanism?
Yes, the output is correct in accordance to C++ standard. But, is it
acceptable just because that is how it is?

Thanks for your contribution as it brought one more point to attention.

Zorro

unread,
Jan 10, 2007, 1:47:08 AM1/10/07
to

Ian, the stream library for output is not the issue. I only tried to
write less because that was not the point. However, you are replacing
division by 0 with a throw. What the example is speaking of is about
exceptions that can happen without you throwing them. Although I am not
saying that your version does not fail.

The concept I am referring to is exceptional events that can happen as
your program executes. For instance, the operating system does not die
on a division by 0. It simply aborts your program. Thus, the point is
that, a C++ compiler's run-time library must sense and report such
events to your program so you can do something about them. Indeed, in
this example the compiler does report. The problem is the way the
run-time library is handling the recovery, known as stack unraveling.
One needs to do a few more things as housekeeping besides popping the
stack, and passing the exception to the next call.

Thanks for your comment.

Kai-Uwe Bux

unread,
Jan 10, 2007, 2:01:12 AM1/10/07
to
Zorro wrote:

>
> Kai-Uwe Bux wrote:
>> Zorro wrote:
>>
>> >
>> > Zorro wrote:
>> >> The simplicity of stack unraveling of C++ is not without defective
>> >> consequences. The following article points to C++ examples showing the
>> >> defects. An engineer aware of defects can avoid hard-to-find bugs.
>> >>
>> >>
>>
http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defective.html
>> >>
>> >> Regards,
>> >> zor...@ZHMicro.com
>> >> http://www.zhmicro.com
>> >> http://distributed-software.blogspot.com
>> >> http://groups-beta.google.com/group/computerlangZ?lnk=la&hl=en
>> >

[snip]


>> > 2. When you say a correct compiler will do better, please specify the
>> > compiler.
>>
>> Your compiler did just fine. The output you present is a perfectly valid
>> output for the program.
>>
>> > 3. Division by 0 happens at system level and is not necessary to turn
>> > it into a throw.
>>
>> The problem with the division by 0 is that it simply is undefined
>> behavior according to the standard. The language specification places no
>> requirements upon the observable behavior of any program that executed a
>> division by 0. Therefore, the output you attribute to incorrect handling
>> of exceptions is a perfectly valid output for your program (and so would
>> be any other).
>>
>> What puts your program into an inconsistent state is not some exception
>> but the division by 0, which is UB.

[snip]


>
> Kai-Uwe, division by 0 is undefined just as trying to deref a null
> pointer. These are exceptional cases that can happen. Simply calling
> them (undefined behavior) does not help in anyway. Are you saying that,
> if one of these cases, or many similar ones, happens the program should
> necessarily terminate? Then what is the point of having an exception
> mechanism?

The try-throw-catch mechanism is not meant to handle those cases. I have
outlined the benefit of try-throw-catch in the following post:

http://groups.google.com/group/comp.lang.c++/browse_frm/thread/2a9904cfe74f5023/e308bdf6553abbc6?lnk=gst&q=Bux+exception+assert&rnum=1#e308bdf6553abbc6


> Yes, the output is correct in accordance to C++ standard. But, is it
> acceptable just because that is how it is?

To me, the current state of affairs with regard to dereferencing a null
pointer or dividing by 0 is acceptable. C++ has basic types that make very
little guarantees. If you want stronger predictability, you should define
simple wrapper classes that provide the additional guarantees. For
instance, I never use pointers directly. Instead I have a simple pointer
wrapper class. It defines operator* so that an assert() is made to catch
dereferencing 0. I also have a wrapper template for the floating point
types (it allows me to overload operator== to do sloppy comparison). This
also catches division by 0.

Also note that this solution is more flexible: I use assert() to catch those
instances, since I consider them bugs. Others may feel that division by 0
is not so much a bug of the program but something due to faulty input. From
that point of view throwing an exception may be more appropriate. I would
not want the language specification make that decision for me.


Best

Kai-Uwe Bux

benben

unread,
Jan 10, 2007, 2:31:21 AM1/10/07
to

So you are actually talking about two separate issues:

1) C++ doesn't throw properly upon divide-by-zero
2) Objects out of scope are not properly destroyed upon divide-by-zero

C++ exception is meant for reporting exceptional circumstances, but for
detecting it. So it is your responsibility to detect and throw properly.

C++ could have properly throw an exception when you try to divide an int
by zero. However, this will put up a significant performance penalty
that not everyone is comfortable with. Alternatively, you can simple
test the divident and throw your own exception:

if (j == 0)
throw divide_by_zero();

i /= j;

This is easy, and you can always create your own type that acts in every
way like an int but throws properly when divided by a zero. So you have
got choices to choose from.

class safe_int
{
int repr;

// ...
};

safe_int operator/=(safe_int lhs, int rhs)
{
if (rhs == 0) throw divide_by_zero();
lhs.repr /= rhs;
return lhs;
}


Once 1) is solved (by using a test or using your own int-like class),
issue 2) is easy. Since the division is no longer a UB, objects out of
scope are guaranteed to be destroyed properly.

Oh btw, please please stop using old compilers!

Regards,
Ben

jalina

unread,
Jan 10, 2007, 2:57:16 AM1/10/07
to
Zorro a écrit :

> Yes, the output is correct in accordance to C++ standard. But, is it
> acceptable just because that is how it is?
>

Well this is how C++ has been defined by "philosophy" (no overhead in
generated code, i.e. no test when dividing to check for 0 division so no
exception raised)

I suggest you to look at the ADA language if you want an exception to be
raised when dividing by 0 (I mean without having to throw it yourself)
or when accessing an invalid index in a array or even when there is an
overflow.

J.

Ian Collins

unread,
Jan 10, 2007, 3:52:32 AM1/10/07
to
Zorro wrote:
> Ian Collins wrote:
>>
>>Which concept?
>>
>
First, please reply inline and trim signatures.

>
> Ian, the stream library for output is not the issue. I only tried to
> write less because that was not the point. However, you are replacing
> division by 0 with a throw. What the example is speaking of is about
> exceptions that can happen without you throwing them. Although I am not
> saying that your version does not fail.
>
Then you aren't talking about exceptions in the C++ sense of the term.
You are talking about events that are beyond the standard.

> The concept I am referring to is exceptional events that can happen as
> your program executes. For instance, the operating system does not die
> on a division by 0. It simply aborts your program. Thus, the point is
> that, a C++ compiler's run-time library must sense and report such
> events to your program so you can do something about them. Indeed, in
> this example the compiler does report. The problem is the way the
> run-time library is handling the recovery, known as stack unraveling.
> One needs to do a few more things as housekeeping besides popping the
> stack, and passing the exception to the next call.
>

It any not be possible for this to happen on many platforms without
checking each and every memory access or operation, which would be
intolerable.

--
Ian Collins.

Dizzy

unread,
Jan 10, 2007, 4:02:03 AM1/10/07
to
Zorro wrote:

> Kai-Uwe, division by 0 is undefined just as trying to deref a null
> pointer. These are exceptional cases that can happen. Simply calling
> them (undefined behavior) does not help in anyway.

It helps in some (other than yours) situations. You see, one design goals of
C++ is to not pay for something you don't use/need. While _you_ would like
the language to check for division by 0 and throw some exception in that
case, others (ME for example) would NOT like it as it will make every
devision in my programs slower for a corner case that I know I never reach.
Thus infriging on my right to have a faster program and on the principle do
not pay a price for what you don't need.

However, at the same time, for people with _your_ needs overloading
operator/ and company (or other wrapper solution) can be implemented:
1. easily
2. it does what you need without making the rest (that don't need it) pay
for what you need

So what we have now with the current C++ is a win/win situation. Why fix it
if it works ?

> Are you saying that,
> if one of these cases, or many similar ones, happens the program should
> necessarily terminate?

No, UB doesn't mean terminate, it's just undefined what it happens. That is
you shouldn't do it and if you are unsure (or you KNOW that you might be
doing it) add checks to avoid it. But for the people (and cases) that are
100% sure it will never happen there are no checks needed thus we have less
overhead when we don't need it.

> Then what is the point of having an exception
> mechanism?

To offer syntax and semantics that make it easy to decouple the place of
error detection with the place of error handling. Also (because it supports
ordinary types and selects the specific type throwed) to make it flexible
in reporting information about the error. But certainly I don't think it
was ment to be used to signal some rare conditions by adding checks where
not all need them and where they can be added easily by those who need
them.

Take another case for example, why doesn't C++ arrays subscript operator
(which are the C arrays actually) and even the standard library containers
(such as vector::operator[]) do not check for range and throw something if
the range is out of bounds ? It is EXACTLY the same reason (however, notice
that std::vector provides .at() that does check I think so you see, you
have a choice).

> Yes, the output is correct in accordance to C++ standard. But, is it
> acceptable just because that is how it is?

For the reasons explained above (which apply to dozens other such decisions
in the C++ standar) YES YES YES! :)

--
Dizzy
http://dizzy.roedu.net

Rolf Magnus

unread,
Jan 10, 2007, 5:35:03 AM1/10/07
to
Zorro wrote:

>
> Zorro wrote:
>> The simplicity of stack unraveling of C++ is not without defective
>> consequences. The following article points to C++ examples showing the
>> defects. An engineer aware of defects can avoid hard-to-find bugs.
>>
>>
http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defective.html
>>
>> Regards,
>> zor...@ZHMicro.com
>> http://www.zhmicro.com
>> http://distributed-software.blogspot.com
>> http://groups-beta.google.com/group/computerlangZ?lnk=la&hl=en
>
> This is a common reply to several comments, respectfully.
>
> 1. The use of one or another header file is cosmetic for this example.

If you are talking about what you consider to be defects in the Standard C++
language, at least you have to use that. Otherwise, your credibility is
gone at that point already.

> 2. When you say a correct compiler will do better, please specify the
> compiler.

The compiler's output _is_ correct, just as any other C++ compiler's is.

> 3. Division by 0 happens at system level and is not necessary to turn
> it into a throw.

Exactly. Anything can happen. You just used one specific compiler that
happens to throw an exception in this case and seems to have a bug. That's
not a proper basis to conclude that there must be a flaw in C++'s exception
handling. On my compiler, an exception is never even thrown by that
program, and C++ doesn't require or even suggest it. So your code basically
has nothing to do with C++ exceptions. It only has to with the behavior of
one specific compiler.

> 4. For this example, the compiler is Microsoft Visual C++ version 6.

Wow, that's an old one. It's not really known for its standard compliance,
but who's to blame it? AFAIK, that compiler is even older than the
standard. It's ancient.

> 5. The defect is in the technique used. Of course it can be corrected.

It is in the implementation of the compiler and your assumptions, not in the
C++ standard.

> Show me a compiler that has in fact corrected this problem. The point
> is that, it takes a great deal beyond plain stack unraveling to correct
> this problem.
> 6. If you are not familiar with the concept, and do not see the real
> issue, avoid revealing it.

Familiar with what concept? You don't seem familiar with the concept of
undefined behavior.

peter koch

unread,
Jan 10, 2007, 7:57:49 AM1/10/07
to

Zorro skrev:

> The simplicity of stack unraveling of C++ is not without defective
> consequences. The following article points to C++ examples showing the
> defects. An engineer aware of defects can avoid hard-to-find bugs.
>
> http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defective.html
>

You use a very old (from before the C-standard) C++ compiler, write a
program that includes non-standard headers and has undefined behavior
and complain that the output is not what you expected.
This makes the statement "an engineer aware of defects can avoid
hard-to-find bugs" funny in a very sad way.
I hope you can do better than that!

/Peter

Roland Pibinger

unread,
Jan 10, 2007, 8:16:27 AM1/10/07
to
On 9 Jan 2007 22:31:06 -0800, "Zorro" wrote:
>division by 0 is undefined just as trying to deref a null
>pointer. These are exceptional cases that can happen. Simply calling
>them (undefined behavior) does not help in anyway.

From K&R B9:
"The header <signal.h> provides facilities for handling exceptional
conditions that arise during execution, such as an inerrupt signal
from an external source or an error in execution.
...
SIGFPE arithmetic error, e.g., zero devide or overflow
...
SIGSEGV illegal storage access, e.g., access outside memory limits"

Erik Wikström

unread,
Jan 10, 2007, 8:24:50 AM1/10/07
to
On Jan 10, 6:39 am, "Zorro" <zor...@comcast.net> wrote:
> This is a common reply to several comments, respectfully.
>
> 3. Division by 0 happens at system level and is not necessary to turn
> it into a throw.

As others have pointed out, this is not an exception. However that does
not mean that there does not exist ways to handle it, on a
POSIX-compatible system you can install a signal-handler for the SIGFPE
(floating-point exception signal), though you always run the risk of
getting a signal for some other kind of exception*, though they are not
that common (they usually terminate the app).

* When I say exception I don't mean a C++ exception but rather a CPU
trap exception.

--
Erik Wikström

Julián Albo

unread,
Jan 10, 2007, 11:35:52 AM1/10/07
to
Zorro wrote:

> 1. The use of one or another header file is cosmetic for this example.

Is not. In several compilers mixing standard headers and pre-standard ones
is not supported.

> 5. The defect is in the technique used. Of course it can be corrected.
> Show me a compiler that has in fact corrected this problem.

The problem is in your code, not in the compiler. Dividing by zero you
invoke undefined behaviour. What your compiler does in that situation, you
must check what your compiler documentation does, and blame his authors if
what you see contradicts his documentation. From the standard point of
view, no matter what it does, is undefined.

--
Salu2

Julián Albo

unread,
Jan 10, 2007, 11:44:29 AM1/10/07
to
Zorro wrote:

> The concept I am referring to is exceptional events that can happen as
> your program executes. For instance, the operating system does not die
> on a division by 0. It simply aborts your program.

What the operating system does has nothing to do with the issue.

> Thus, the point is that, a C++ compiler's run-time library must sense and
> report such events to your program so you can do something about them.

The point is that all compilers must do what you want just because you like
it that way? If not, there are tons of books and other resources that
explains the reasons for the design decisions of the C++ language.

--
Salu2

Simon G Best

unread,
Jan 10, 2007, 1:22:59 PM1/10/07
to
Hello!

Zorro wrote:
> The simplicity of stack unraveling of C++ is not without defective
> consequences. The following article points to C++ examples showing the
> defects. An engineer aware of defects can avoid hard-to-find bugs.
>
> http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defective.html

I've read this thread, as well as your blog article and referenced
document (which seems to be plugging your Z++), and it seems you're
misunderstanding /why/ the behaviour of division by zero is undefined.

My guess is that the rationale behind it being undefined is something
like the following.

When a processor encounters division by zero, it may well throw an
exception (*not* a C++ exception), complain in some other way, ignore
it, or do something else. What it does depends on the processor. But,
whatever it is, it's beyond the scope of the C++ standard, because the
C++ standard is not there to define such processor behaviour.

If a processor somehow reports division by zero to, say, an operating
system, then that operating system may well respond by sending a signal
to the relevant program, terminating execution of that program, ignoring
it, or doing something else. What it does depends on the operating
system. But, whatever it is, it's beyond the scope of the C++ standard,
because the C++ standard is not there to define such operating system
behaviour.

If the C++ standard was to specify behaviour for division by zero, then
since the processor's behaviour and operating system's behaviour are
beyond the scope of the C++ standard, such specified behaviour may well
have to be implemented in such a way as to prevent the division by zero
from actually occurring in the first place. That would impose often
unnecessary and unwanted overheads. C++ just isn't that sort of language.

Indeed, there are a great many unsafe things that C++ allows programmers
to do. There are unsafe things that C++ allows programmers to do
without even throwing C++ exceptions when they're done. Instead, C++
provides mechanisms for use /when the programmer wants or needs them./
It's the programmer's responsibility to write safe code, /not/ C++
itself. So, C++ provides exception mechanisms /without/ imposing them
on the programmer. If the programmer needs well-behaved exception
handling, the programmer can then use the exception mechanisms provided
accordingly. That's the kind of language that C++ is.

So, if, when doing a division, there's the real (though hopefully
exceptional) possibility of it being a division by zero, the thing to do
is to do that division within a try block, checking for division by zero
before doing the division, and throwing an exception if it would be
division by zero. This could, of course, be wrapped up in your own
number class. No need to change the language itself.

:-)

--
Simon G Best
What happens if I mention Leader Kibo in my .signature?

IR

unread,
Jan 10, 2007, 2:44:26 PM1/10/07
to
Zorro wrote:
> 5. The defect is in the technique used. Of course it can be
> corrected. Show me a compiler that has in fact corrected this
> problem. The point is that, it takes a great deal beyond plain
> stack unraveling to correct this problem.

Basically, you're just saying that RAII in C++ is broken.
This is a tough statement, you're gonna have hard time proving it...

Incidentally, as others already mentionned it, you should start using
a recent compiler.

Cheers,
--
IR

Zorro

unread,
Jan 11, 2007, 1:03:21 AM1/11/07
to

There are a number of great comments, but this one sums it up rather
thoroughly.

What seems to be happening is this. When you use "throw", the compiler
generates code to destroy objects in relevant scopes, should an
exception happen. Otherwise, the compiler has no clue where to put such
code. Thus, even though exceptions (such as div by zero) are caught,
the code to call destructors (at end of try, or function body) is
simply skipped.

What that all means, again is this. There is code to destroy objects in
nested scopes. However, unless the "throw" is used, the compiler will
be caught unguarded, and code for destroying objects will be skipped.

That is fair as a standard. The compiler is just doing what the
standard requires, even VC++ 6 does it right. It is also fair to expect
the engineer to check for every possible case of exception and put a
"throw" for it.

I have no further argument on this issue. Just a comment, and nothing
else.

Given that all operating systems report errors (exceptions) rather than
crashing, and in fact the program can even check the error code, etc.
and continue to execute (perhaps taking the necessary actions), how
hard is it for the standard to have a list of common exceptions that
may happen unexpectedly?
The answer is that, the mechanism used in C++ still will need the
"throw" in order to generate code for NOT skipping the destruction of
objects.
I hope this helps, but it is not intended to start another wave. I
agree with all of you.

Thanks for your comments. Have a great day.

Julián Albo

unread,
Jan 11, 2007, 1:38:27 AM1/11/07
to
Zorro wrote:

> Given that all operating systems report errors (exceptions) rather than
> crashing, and in fact the program can even check the error code, etc.

Invalid reasoning, because the premise is false. Unless you use a definition
of "Operating system" that excludes, for example, ms-dos.

--
Salu2

Ian Collins

unread,
Jan 11, 2007, 2:29:56 AM1/11/07
to
Zorro wrote:
>
> Given that all operating systems report errors (exceptions) rather than
> crashing, and in fact the program can even check the error code, etc.
> and continue to execute (perhaps taking the necessary actions), how
> hard is it for the standard to have a list of common exceptions that
> may happen unexpectedly?

Not all implementations are hosted. Even those that are (UNIX like
systems for example) may signal exception asynchronously. This makes it
extremely difficult to handle the event in the same context as the
running application in order to convert the system event into an
application one.

--
Ian Collins.

Pete Becker

unread,
Jan 11, 2007, 6:40:51 AM1/11/07
to
Zorro wrote:
>
> What seems to be happening is this. When you use "throw", the compiler
> generates code to destroy objects in relevant scopes, should an
> exception happen. Otherwise, the compiler has no clue where to put such
> code. Thus, even though exceptions (such as div by zero) are caught,
> the code to call destructors (at end of try, or function body) is
> simply skipped.
>

No. If div by zero throws an exception that's implementation-specific
behavior. If your implementation does something silly like not run
destructors as part of its implemenation-specific behavior, that's a
problem with your implementation, not with the language.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)

dasjotre

unread,
Jan 11, 2007, 7:26:12 AM1/11/07
to

Zorro wrote:
> how
> hard is it for the standard to have a list of common exceptions that
> may happen unexpectedly?

I suspect much harder than it is for you to write

#include <eh.h>

void my_handler(UINT, struct _EXCEPTION_POINTERS* pex)
{
if(pex->ExceptionRecord->ExceptionCode ==
EXCEPTION_INT_DIVIDE_BY_ZERO)
throw divide_by_zero();
}

// main
_set_se_translator(&my_handler);

Pete Becker

unread,
Jan 11, 2007, 8:30:54 AM1/11/07
to
Zorro wrote:
> how
> hard is it for the standard to have a list of common exceptions that
> may happen unexpectedly?

The standard has a list of all standard exceptions. Keep in mind that
hardware "exceptions" are not the same as C++ exceptions, although they
use the same name. C++ doesn't say much about hardware exceptions,
because they're too idiosyncratic. If you don't throw it, it's not
covered by the standard.

Mathias Gaunard

unread,
Jan 11, 2007, 2:59:44 PM1/11/07
to
Zorro wrote:

> What seems to be happening is this. When you use "throw", the compiler
> generates code to destroy objects in relevant scopes, should an
> exception happen. Otherwise, the compiler has no clue where to put such
> code. Thus, even though exceptions (such as div by zero) are caught,
> the code to call destructors (at end of try, or function body) is
> simply skipped.

You're wrong.
`throw' simply throws exceptions.
If you don't use `throw', no exception is thrown. `throw' is the only
way to throw exceptions in C++.
It has been told to you more than ten times already, but division by
zero does *not* throw any exception.

> Given that all operating systems report errors (exceptions) rather than
> crashing

Not all do, on some machines couldn't even allow it.

Old Wolf

unread,
Jan 11, 2007, 9:25:53 PM1/11/07
to

Not particularly useful to the case in hand, as undefined
behaviour is caused if the signal handler for either of those
signals is not present, or returns (ie. to have defined behaviour
you must have a signal handler which aborts the program).

Zorro

unread,
Jan 12, 2007, 2:23:48 AM1/12/07
to

This is an interesting point. Indeed, there is something good in every
comment that helps design safer applications. Let me ask the question
from a different angle, though your comment does not focus on this
aspect of the question. Think of a complex program with a large number
of exceptions, and the possibility of missing something (to be done
later).

If my application did not throw an exception, and it was caused by
external events, why was it caught? I would be more than happy to see
my program crash so I could find my problem. On the other hand, if an
exceptional event can be caught by the runtime library, how come it
cannot clean up properly?

Please do not focus on div-by-zero. Think of some exceptional event,
call it unknown. So, either the catch() can trap unknown exceptions
caused by underlying system (thus, it must clean up correctly), or my
application must crash, as it would without the use of catch().

Is this a fair question?

Please, let us not blame a particular compiler implementation. This is
not specific to any compiler. Try it with your favorite compiler.

Erik Wikström

unread,
Jan 12, 2007, 2:52:00 AM1/12/07
to
On Jan 12, 8:23 am, "Zorro" <zor...@comcast.net> wrote:
> Ian Collins wrote:
> > Zorro wrote:
>
> > > Given that all operating systems report errors (exceptions) rather than
> > > crashing, and in fact the program can even check the error code, etc.
> > > and continue to execute (perhaps taking the necessary actions), how
> > > hard is it for the standard to have a list of common exceptions that
> > > may happen unexpectedly?
>
> > Not all implementations are hosted. Even those that are (UNIX like
> > systems for example) may signal exception asynchronously. This makes it
> > extremely difficult to handle the event in the same context as the
> > running application in order to convert the system event into an
> > application one.
>
> This is an interesting point. Indeed, there is something good in every
> comment that helps design safer applications. Let me ask the question
> from a different angle, though your comment does not focus on this
> aspect of the question. Think of a complex program with a large number
> of exceptions, and the possibility of missing something (to be done
> later).
>
> If my application did not throw an exception, and it was caused by
> external events, why was it caught? I would be more than happy to see
> my program crash so I could find my problem. On the other hand, if an
> exceptional event can be caught by the runtime library, how come it
> cannot clean up properly?

Easy, it was caught because your compiler vendor decided that they
wanted it that way, as others have pointed out earlier division by 0
causes undefined behaviour, which is just that: undefined. Meaning that
just because it was caught on your system there is no guarantee that it
will on someone else system, or your system with a small upgrade, or
whatever. Once a program has entered undefined behaviour anything is
possible, it might even continue and execute the rest of the program
correctly.

--
Erik Wikström

Ian Collins

unread,
Jan 12, 2007, 4:26:21 AM1/12/07
to
Zorro wrote:
> Ian Collins wrote:
>
>>Zorro wrote:
>>
>>>Given that all operating systems report errors (exceptions) rather than
>>>crashing, and in fact the program can even check the error code, etc.
>>>and continue to execute (perhaps taking the necessary actions), how
>>>hard is it for the standard to have a list of common exceptions that
>>>may happen unexpectedly?
>>
>>Not all implementations are hosted. Even those that are (UNIX like
>>systems for example) may signal exception asynchronously. This makes it
>>extremely difficult to handle the event in the same context as the
>>running application in order to convert the system event into an
>>application one.
>>
Please trim signatures (your news reader should be set to do this for
you). You should also add a -- line before yours so news readers can
recognise it for what it is.

>
> This is an interesting point. Indeed, there is something good in every
> comment that helps design safer applications. Let me ask the question
> from a different angle, though your comment does not focus on this
> aspect of the question. Think of a complex program with a large number
> of exceptions, and the possibility of missing something (to be done
> later).
>
> If my application did not throw an exception, and it was caused by
> external events, why was it caught? I would be more than happy to see
> my program crash so I could find my problem. On the other hand, if an
> exceptional event can be caught by the runtime library, how come it
> cannot clean up properly?
>
I think that is where you make your mistake, the event need not be
caught by the runtime library. It is more likely to be caught by the
operating system (if the environment is hosted) as a result of a trap
generated by the underlying hardware. The means of delivery is
dependant on the operating environment, not the running application
(which includes the C++ runtime).

The rules relating to the handling of these events are laid down by the
operating environment, not the C++ runtime. There may be some event
that can be handled by the runtime, but it is beyond the scope of the
C++ standard to mandate how these are handled for all environments.

As I said before, in a UNIX like environment, hardware exceptions are
handled through a form of software interrupt known as a signal. The
signal is processed in a different context from the application and
there isn't a means of communicating between the signal handler and the
application context. The same would apply to any system using
interrupts to handle exceptions raised by the processor.

--
Ian Collins.

Pete Becker

unread,
Jan 12, 2007, 7:25:04 AM1/12/07
to
Zorro wrote:
>
> Please, let us not blame a particular compiler implementation. This is
> not specific to any compiler. Try it with your favorite compiler.
>

On the contrary: catching exceptions that were not thrown is not part of
standard C++. If your implementation does this, you need to ask your
compiler vendor for details and, perhaps, for an explanation of how to
use it.

Zorro

unread,
Jan 12, 2007, 11:21:53 AM1/12/07
to

OK. This is a direct answer, and I appreciate it. Let us be more
specific.

"Catching exceptions that were not thrown is not part of standard C++".

Does this mean:

1. Exception must not be caught (generally, the program will crash).
2. Whether or not catch it is vendor-specific (outside of standard,
hence arbitrary).
3. Program becomes undefined with unpredictable behavior (hardly
useful).

Erik Wikström

unread,
Jan 12, 2007, 11:56:32 AM1/12/07
to
On 2007-01-12 17:21, Zorro wrote:
> Pete Becker wrote:
>> Zorro wrote:
>> >
>> > Please, let us not blame a particular compiler implementation. This is
>> > not specific to any compiler. Try it with your favorite compiler.
>> >
>>
>> On the contrary: catching exceptions that were not thrown is not part of
>> standard C++. If your implementation does this, you need to ask your
>> compiler vendor for details and, perhaps, for an explanation of how to
>> use it.
>>
>> --
>>
>> -- Pete
>> Roundhouse Consulting, Ltd. (www.versatilecoding.com)
>> Author of "The Standard C++ Library Extensions: a Tutorial and
>> Reference." (www.petebecker.com/tr1book)
>
> OK. This is a direct answer, and I appreciate it. Let us be more
> specific.
>
> "Catching exceptions that were not thrown is not part of standard C++".
>
> Does this mean:
>
> 1. Exception must not be caught (generally, the program will crash).
> 2. Whether or not catch it is vendor-specific (outside of standard,
> hence arbitrary).
> 3. Program becomes undefined with unpredictable behavior (hardly
> useful).

It means that if you have code with a catch-block that gets executed
even though no exception has been thrown it is not standard compliant
behaviour, I would even go as far as saying that it is in direct
violation of the standard.

Just to be clear, that is not what is happening in your code, what
happens there is that you get undefined behavior. And when you get UB
anything is fair, so executing the catch-block is not exactly wrong.

--
Erik Wikström

Pete Becker

unread,
Jan 12, 2007, 12:08:36 PM1/12/07
to
Zorro wrote:
> Pete Becker wrote:
>> Zorro wrote:
>>> Please, let us not blame a particular compiler implementation. This is
>>> not specific to any compiler. Try it with your favorite compiler.
>>>
>> On the contrary: catching exceptions that were not thrown is not part of
>> standard C++. If your implementation does this, you need to ask your
>> compiler vendor for details and, perhaps, for an explanation of how to
>> use it.
>>
>> --
>>
>> -- Pete
>> Roundhouse Consulting, Ltd. (www.versatilecoding.com)
>> Author of "The Standard C++ Library Extensions: a Tutorial and
>> Reference." (www.petebecker.com/tr1book)
>
> OK. This is a direct answer, and I appreciate it. Let us be more
> specific.
>
> "Catching exceptions that were not thrown is not part of standard C++".
>
> Does this mean:
>
> 1. Exception must not be caught (generally, the program will crash).
> 2. Whether or not catch it is vendor-specific (outside of standard,
> hence arbitrary).
> 3. Program becomes undefined with unpredictable behavior (hardly
> useful).
>

It means that the standard does not address it. Again: if your

Pete Becker

unread,
Jan 12, 2007, 12:11:52 PM1/12/07
to
Erik Wikström wrote:
>
> It means that if you have code with a catch-block that gets executed
> even though no exception has been thrown it is not standard compliant
> behaviour, I would even go as far as saying that it is in direct
> violation of the standard.
>
> Just to be clear, that is not what is happening in your code, what
> happens there is that you get undefined behavior. And when you get UB
> anything is fair, so executing the catch-block is not exactly wrong.
>

If a program has undefined behavior under the standard, the standard
does not impose any requirements. In particular, the compiler is free to
generate code that executes catch clauses even when there is no
corresponding throw.

Simon G Best

unread,
Jan 12, 2007, 12:12:11 PM1/12/07
to
Zorro wrote:
> Pete Becker wrote:
>>>
>> On the contrary: catching exceptions that were not thrown is not part of
>> standard C++. If your implementation does this, you need to ask your
>> compiler vendor for details and, perhaps, for an explanation of how to
>> use it.
>
> OK. This is a direct answer, and I appreciate it. Let us be more
> specific.
>
> "Catching exceptions that were not thrown is not part of standard C++".
>
> Does this mean:
>
> 1. Exception must not be caught (generally, the program will crash).

No. An exception that isn't thrown doesn't even exist. For an
exception to exist, it must be thrown. The throwing of an exception is
the creation of that exception.

Again, things that may be regarded as exceptions /outside/ of C++ /are
not/ C++ exceptions. A processor exception /is not an exception in
C++./ An exception thrown by an operating system /is not an exception
in C++./ The /only/ exceptions in C++ are exceptions thrown /within/ C++.

So, in a sense, yes: 'exceptions' that are not thrown /within/ C++
should not be caught /within/ C++. Except, of course, when it's a case
of undefined behaviour (such as with division by zero), in which case
anything's allowed to happen (including catching exceptions that weren't
thrown). That's what "undefined" means.

Marcus Kwok

unread,
Jan 12, 2007, 1:56:54 PM1/12/07
to
Zorro <zor...@comcast.net> wrote:
> The simplicity of stack unraveling of C++ is not without defective
> consequences. The following article points to C++ examples showing the
> defects. An engineer aware of defects can avoid hard-to-find bugs.
>
> http://distributed-software.blogspot.com/2007/01/c-exception-handling-is-defective.html

It seems you have confused C++ exceptions with "structured exception
handling" (SEH). SEH is provided as a Microsoft extension (you said you
were using VC++ 6.0), and Microsoft specifically says that SEH is not
specifically designed for, nor is it recommended, for C++, and that
regular C++ exception handling should be used in a C++ program.

If you use SEH, you must instead use the non-standard __try/__finally
construct.

See the following links for more information. Incidentally, one of the
examples demonstrates it with a divide-by-zero error:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_core_exception_handling_differences.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_core_using_structured_exception_handling_with_c.2b2b.asp

--
Marcus Kwok
Replace 'invalid' with 'net' to reply

Ian Collins

unread,
Jan 12, 2007, 2:14:42 PM1/12/07
to
Zorro wrote:
> Pete Becker wrote:
>
>>Zorro wrote:
>>
>>>Please, let us not blame a particular compiler implementation. This is
>>>not specific to any compiler. Try it with your favorite compiler.
>>>
>>
>>On the contrary: catching exceptions that were not thrown is not part of
>>standard C++. If your implementation does this, you need to ask your
>>compiler vendor for details and, perhaps, for an explanation of how to
>>use it.
>>
>
> OK. This is a direct answer, and I appreciate it. Let us be more
> specific.
>
Please follow the advice I posted on quoting and using signatures, it
will make your posts easier to follow.

> "Catching exceptions that were not thrown is not part of standard C++".
>

Such a beast does not exist. Something that isn't created with a throw
simply isn't an exception!

--
Ian Collins.

Zorro

unread,
Jan 12, 2007, 4:15:49 PM1/12/07
to

Thanks for the links Marcus. They make it clear that, if you do use
throw the destructors will be called with much less overhead. But if
you miss on some possible exception that may occur, then the jump to
the catch section will occur but the clean up may not be done as needed
(In MS context). Thus, it is the engineer that must remember every
little detail.

I was not talking about how to catch other kinds of exceptions (given
that I remember them in a complex program), but the comments went in
that direction. Also, I am saying this behavior is not unique to VC++.
If that were the case, this would end the discussion.

Whether or not a raised exception is "thrown", the control from the try
block makes a jump to the catch() section. That is what I meant by
"catching none-thrown exceptions".

Thanks again.

Zorro

unread,
Jan 12, 2007, 4:24:36 PM1/12/07
to

I will try to bring together your comments as a reply to Simon. My
apologies should I misinterpret your comments.

Replying to Simon.

You are very specific about not catching exceptions that were not
thrown within a program, because they do not even exist. This settles
the main aspect of the issue, assuming that is how the standard
stipulates this matter.
Then, you add, other events such as "file not found", "read
error" and "div by 0" put the program in an undefined state in
which it may behave in an undefined manner. I am asking if the standard
uses the term "undefined" in this context. Here is what Pete says.

"It means that the standard does not address it. Again: if your


implementation does this, you need to ask your compiler vendor for
details and, perhaps, for an explanation of how to use it".

So, does "undefined" mean that the standard does not address it, or
does it mean that the standard specifically mentions, "undefined
behavior"?

Erik says "It means that if you have code with a catch-block that


gets executed even though no exception has been thrown it is not

standard compliant behavior, I would even go as far as saying that it


is in direct violation of the standard".

A very specific and clear statement. But again, Erik immediately brings
up undefined behavior.

Is "undefined behavior", in this context, mentioned in the
standard? It will be nice someone familiar with standard to kindly
tells us where this is stated.

My opinion is what it was some 20 years ago with regard to the
implementation in the experimental compiler.

"If your design requires the use of throw in order to behave
logically, then it must remain oblivious with regard to an exception
not raised by a throw".

Please note that what this means is the following "For any exception
not thrown in a try block, the control must not jump to the catch
section".

Finally, considering the difficulty of implementation, it is fine to
make the jump (i.e. catch any exception as it comes), without having a
corresponding name for it. Just label them as "Unknown Exception",
but do the clean up so the program does not behave unpredictably.

The best way to resolve this is an answer like this. Standard item
number such and such states that .... Or, standard does not address
this issue for now.

Please note the following, which seems to get lost in your replies.

"When the majority (if not all) compilers do the same thing, one
takes the behavior for granted very much like an implicit standard.
Specifically, for exceptions not thrown by an application, they make
the jump to the catch section (the exceptions are caught anyway)".

You are addressing this issue by pointing to a particular example that
I have presented as "undefined". So, are you saying any none-thrown
exception is "undefined"? If not, can you give an example (and your
choice of compiler) that "does not catch a none-thrown exception"?

Simon G Best

unread,
Jan 12, 2007, 4:27:16 PM1/12/07
to
Zorro wrote:
>
> Whether or not a raised exception is "thrown", the control from the try
> block makes a jump to the catch() section. That is what I meant by
> "catching none-thrown exceptions".

Exceptions are raised *by throwing them.* In C++, that's what raising
an exception is. You can't have a raised exception that isn't thrown,
because you can't have a /thrown/ exception that isn't thrown.

Ian Collins

unread,
Jan 12, 2007, 4:36:47 PM1/12/07
to
Zorro wrote:

*PLEASE* follow my advice on regarding signatures!


>
> Please note the following, which seems to get lost in your replies.
>
> "When the majority (if not all) compilers do the same thing, one
> takes the behavior for granted very much like an implicit standard.
> Specifically, for exceptions not thrown by an application, they make
> the jump to the catch section (the exceptions are caught anyway)".
>

The only platform I know that does this in windows, so there isn't any
de facto standard here.

> You are addressing this issue by pointing to a particular example that
> I have presented as "undefined". So, are you saying any none-thrown
> exception is "undefined"? If not, can you give an example (and your
> choice of compiler) that "does not catch a none-thrown exception"?
>

It's beyond undefined, it's outside of the scope of the C++ standard and
squarely in the scope of the operating environment.

If the operating environment chooses to abort an application in the
event of a asynchronous event, there is nothing the C++ compiler can do
to circumvent this behaviour.

--
Ian Collins.

Zorro

unread,
Jan 12, 2007, 5:23:35 PM1/12/07
to

In response to several comments after this posting:

Let us be fair. Do not reply to a paragraph, somewhat out ot context. I
am asking a couple of specific questions. If someone is familiar with
the standard, please point out where should we look in the standard.
Please, kindly show an example, and your choice of compiler, as I have
requested. Some of the comments simply say "Only MS VC++ does that".
Well, can you create an example using another compiler that does not?
Playing with words can go on forever, such as "An exception that is not
thrown is not an exception".
Please show an example that does not do what I am saying is happening.
Do not simply say that it is not happening. Show us how it is not
happening.

Please read the whole comment and kindly provide an answer to the
questions asked, not to individual phrases.

Thank you very much for all your input, so far.

Regards.

Erik Wikström

unread,
Jan 12, 2007, 5:28:24 PM1/12/07
to
On 2007-01-12 22:24, Zorro wrote:
> Simon G Best wrote:
>
> Erik says "It means that if you have code with a catch-block that
> gets executed even though no exception has been thrown it is not
> standard compliant behavior, I would even go as far as saying that it
> is in direct violation of the standard".
>
> A very specific and clear statement. But again, Erik immediately brings
> up undefined behavior.

Sorry if that was unclear, what I meant to say was that while I can't
cite any specific part of the standard I'm quite sure that it specifies
that all exceptions have to be throw. As no such things happens in your
example I claim that there is no exception.

> Is "undefined behavior", in this context, mentioned in the
> standard? It will be nice someone familiar with standard to kindly
> tells us where this is stated.

[snip]

> The best way to resolve this is an answer like this. Standard item
> number such and such states that .... Or, standard does not address
> this issue for now.

I don't own a copy of the standard but I've got a copy of a draft for
the next standard, which I hope will suffice.

1.3.13 undefined behavior [defns.undefined]

behavior, such as might arise upon use of an erroneous program construct
or erroneous data, for which this International Standard mposes no
requirements. Undefined behavior may also be expected when this
International Standard omits the description of any explicit definition
of behavior. [ Note: permissible undefined behavior ranges from ignoring
the situation completely with unpredictable results, to behaving during
translation or program execution in a documented manner characteristic
of the environment (with or without the issuance of a diagnostic
message), to terminating a translation or execution (with the issuance
of a diagnostic message). Many erroneous program constructs do not
engender undefined behavior; they are required to be diagnosed. —end note ]

The following might also be of interest:

5.6 Multiplicative operators [expr.mul]

4th paragraph

The binary / operator yields the quotient, and the binary % operator
yields the remainder from the division of the first expression by the
second. If the second operand of / or % is zero the behavior is
undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are
nonnegative then the remainder is nonnegative; if not, the sign of the
remainder is implementation-defined).

Hope that helps.

--
Erik Wikström

Ian Collins

unread,
Jan 12, 2007, 5:34:22 PM1/12/07
to
Zorro wrote:
>
> In response to several comments after this posting:
>
> Let us be fair. Do not reply to a paragraph, somewhat out ot context. I
> am asking a couple of specific questions. If someone is familiar with
> the standard, please point out where should we look in the standard.

This is out of the scope of the standard!

> Please, kindly show an example, and your choice of compiler, as I have
> requested. Some of the comments simply say "Only MS VC++ does that".
> Well, can you create an example using another compiler that does not?
> Playing with words can go on forever, such as "An exception that is not
> thrown is not an exception".
> Please show an example that does not do what I am saying is happening.
> Do not simply say that it is not happening. Show us how it is not
> happening.
>

This is becoming tedious.

Your own example:

#include <iostream>

struct simple
{
int s;
simple() { s = 5;}
~simple(void) {std::cout << "Destructor ..." << std::endl;}
};

int main(){
int i = 1, j = 0;
try {
simple spl;
int k = i/j;
}
catch(...) {
std::cout << "Caught it" << std::endl;
}
std::cout << "Finishing" << std::endl;
return 0;
}

compiled with gcc on Solaris or Linux aborts.

./a.out
Arithmetic Exception (core dumped)

--
Ian Collins.

Simon G Best

unread,
Jan 12, 2007, 5:41:55 PM1/12/07
to
Just to clarify...

Ian Collins wrote:
>
> ./a.out
> Arithmetic Exception (core dumped)

That "Arithmetic Exception", I bet, is *not* a C++ exception, but some
other kind of exception beyond C++. (Just thought I'd better clarify
that, just in case Zorro mistakes it for a C++ exception.)

Erik Wikström

unread,
Jan 12, 2007, 5:58:25 PM1/12/07
to
On 2007-01-12 23:28, Erik Wikström wrote:
> On 2007-01-12 22:24, Zorro wrote:
>> Simon G Best wrote:
>>
>> Erik says "It means that if you have code with a catch-block that
>> gets executed even though no exception has been thrown it is not
>> standard compliant behavior, I would even go as far as saying that it
>> is in direct violation of the standard".
>>
>> A very specific and clear statement. But again, Erik immediately brings
>> up undefined behavior.
>
> Sorry if that was unclear, what I meant to say was that while I can't
> cite any specific part of the standard I'm quite sure that it specifies
> that all exceptions have to be throw. As no such things happens in your
> example I claim that there is no exception.

Sorry, no, that is not what I meant. My only excuse is that it's quite
late. What I really meant was that I'm quite sure that the standard
specifies that the code in a catch-block may only be executed if an
exception is thrown in the preceding try-block. So executing the catch-
block when no exception has been thrown is in violation of the standard.

--
Erik Wikström

Erik Wikström

unread,
Jan 12, 2007, 6:06:51 PM1/12/07
to
On 2007-01-12 23:23, Zorro wrote:
> In response to several comments after this posting:
>
> Let us be fair. Do not reply to a paragraph, somewhat out ot context. I
> am asking a couple of specific questions. If someone is familiar with
> the standard, please point out where should we look in the standard.
> Please, kindly show an example, and your choice of compiler, as I have
> requested. Some of the comments simply say "Only MS VC++ does that".
> Well, can you create an example using another compiler that does not?
> Playing with words can go on forever, such as "An exception that is not
> thrown is not an exception".

It's not, chapter 15, first paragraph states:

Exception handling provides a way of transferring control and
information from a point in the execution of a program to an exception
handler associated with a point previously passed by the execution. A
handler will be invoked only by a throw-expression invoked in code
executed in the handler’s try block or in functions called from the
handler’s try block.

The handler here is the catch-block.

--
Erik Wikström

Zorro

unread,
Jan 12, 2007, 7:14:10 PM1/12/07
to
> engender undefined behavior; they are required to be diagnosed. -end note ]

>
> The following might also be of interest:
>
> 5.6 Multiplicative operators [expr.mul]
>
> 4th paragraph
>
> The binary / operator yields the quotient, and the binary % operator
> yields the remainder from the division of the first expression by the
> second. If the second operand of / or % is zero the behavior is
> undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are
> nonnegative then the remainder is nonnegative; if not, the sign of the
> remainder is implementation-defined).
>
> Hope that helps.
>
> --
> Erik Wikström

Yes Erik, it helps me completely. Thanks. I actually needed this info
for improving on the article. Good night.

Regards.

Zorro

unread,
Jan 12, 2007, 7:47:33 PM1/12/07
to

Yes Ian. gcc gave me "Floating point Exception". The compilers from
Metrowerks, Borland and MS were on PC and it seemed sufficient to show
the problem, without trying a free compiler (and retyping the program).
That proved to be wrong.

Thanks.
Regards.

Zorro

unread,
Jan 12, 2007, 7:52:18 PM1/12/07
to

No Simon, I do not mistake it. This exception is equivalent to a crash,
as one would expect to happen.

Regards.

Grizlyk

unread,
Jan 14, 2007, 6:42:20 AM1/14/07
to
benben wrote:
>
> C++ could have properly throw an exception when you try to divide an int
> by zero. However, this will put up a significant performance penalty
> that not everyone is comfortable with. Alternatively, you can simple
> test the divident and throw your own exception:
>
> if (j == 0)
> throw divide_by_zero();
>
> i /= j;

Can not, divide by zero can happen not only for zero, try divide 0xffff
to 0x02, test it in debug
write to file:"
r ax
ffff
r dx
2
a
div dl

r
t
q
"
write to command line:"
>debug <file
"
But compiler easy can setup trap for the error and throw divide_by zero
exception.

It seems to me, that there is no std::divide_by zero exception, so it
is really interesting problem, thanks Zorro.

Simon G Best wrote:
> >
> >I f the C++ standard was to specify behaviour for division by zero, then
> > since the processor's behaviour and operating system's behaviour are
> > beyond the scope of the C++ standard, such specified behaviour may well
> > have to be implemented in such a way as to prevent the division by zero
> > from actually occurring in the first place. That would impose often
> > unnecessary and unwanted overheads. C++ just isn't that sort of language.

It looks like " We do not want to process the error, and will try to
find a cause of it, if we will not find any, we will not process the
error also. Abtreten! " :)

Speaking seriously, the ignoring the error as "undefined behaviour" may
be is not a best solution, because most CPUs can handle the error and
compilers must do good workaround (they do not do it itself), and if
CPU can not, the kind of C++ exception just will never appear.

I think, user can not effective manage the error, because can not jump
to hidden catch entry point directly, because trap can be executed in
other task(process) from which user can not throw, so user must do
unneccessary if-else after each divide operation, that is no good.

Simon G Best

unread,
Jan 14, 2007, 1:53:43 PM1/14/07
to
Grizlyk wrote:
>
> Can not, divide by zero can happen not only for zero, try divide 0xffff
> to 0x02, test it in debug

Interesting. Is that because, on your architecture, 0xFFFF is -0? (I'm
just guessing.)

> But compiler easy can setup trap for the error and throw divide_by zero
> exception.

But we don't want the unnecessary overhead when there's no possibility
of divide-by-zero. C++ leaves it to the programmer to decide whether or
not checks are needed, rather than imposing such checks.

> Simon G Best wrote:
>>> I f the C++ standard was to specify behaviour for division by zero, then
>>> since the processor's behaviour and operating system's behaviour are
>>> beyond the scope of the C++ standard, such specified behaviour may well
>>> have to be implemented in such a way as to prevent the division by zero
>>> from actually occurring in the first place. That would impose often
>>> unnecessary and unwanted overheads. C++ just isn't that sort of language.
>
> It looks like " We do not want to process the error, and will try to
> find a cause of it, if we will not find any, we will not process the
> error also. Abtreten! " :)

Sorry, I just didn't understand that. "try to find a cause of it"? "if
we will not find any, we will not process the error also"?

> Speaking seriously, the ignoring the error as "undefined behaviour" may
> be is not a best solution, because most CPUs can handle the error and
> compilers must do good workaround (they do not do it itself), and if
> CPU can not, the kind of C++ exception just will never appear.

I didn't understand the second half of that. But as for "may be is not
a best solution, because most CPUs can handle the error", the problem is
that (as I understand it) the operating system deals with such things.
Different operating systems deal with such things in different ways.
And, as I said above, such things are beyond the scope of the C++
specification.

> I think, user can not effective manage the error, because can not jump
> to hidden catch entry point directly, because trap can be executed in
> other task(process) from which user can not throw, so user must do
> unneccessary if-else after each divide operation, that is no good.

Such checking only needs to be done in those cases where undefined
behaviour would otherwise be possible, and would be unacceptable. Such
checks don't need to be done for those cases where such undefined
behaviour isn't able to occur anyway.

For example, let's suppose that a program is going to be reading in some
data from somewhere. Let's also suppose that it's possible for that
data to be 'incorrect' in some way (even though it's obviously not
supposed to be incorrect, it still might be). And let's also suppose
that we need that program to behave well even when 'incorrect' data is
given to it. And finally, let's suppose it's possible for that data to
be 'incorrect' in such a way that normal processing of that data could
involve division by zero.

In order to have that program behave well when given such 'incorrect'
data, we're going to have to check the data somehow, and take
appropriate action when that data's 'incorrect'. That's the sort of
thing we can use exceptions for. (And we may well have that data
checking some way before it even gets close to any of the relevant
divisions, so we might not even have to specifically check for division
by zero.)

In contrast, if part of a program can't ever end up trying to do
something like division by zero, then there's no need to check for such
things as division by zero. No need to add the extra overhead of
checking for such cases when such cases can't arise anyway. For example:-

int foo (int x) {
for (int i(1); i <= 10; ++i) // i can't ever be zero, so
x /= i; // no check is ever needed.
return x;
}

As usual, C++ does not impose safety on the programmer; instead, it
provides tools to help the programmer write safe code.

:-)

Zorro

unread,
Jan 14, 2007, 3:39:45 PM1/14/07
to

Simon G Best wrote:
>
> As usual, C++ does not impose safety on the programmer; instead, it
> provides tools to help the programmer write safe code.
>
> :-)
>
> --
> Simon G Best
> What happens if I mention Leader Kibo in my .signature?

Thanks to all comments, and in particular yours (to my blogger) I
realized I had made a slieght error because multiple compilers gave me
the same result (on Windows). My apologies. However ...

I have redone the blogger, and the article to show the disadvantages of
C++ exception model, and a better way of doing things. Looking at your
comment (above) I do not see what you are really trying to say. What do
you mean by "C++ does not impose safety on the programmer". So, how
come you cannot call a private method? It is the purpose of a modern
language to help with the safety.

Then you say "C++ provides tools ....". Does C not do that already? So
why use C++?

Now, reread the article, without prejudice. I love C++ and I have known
it from the time before it was called C++. My argument is that,
someone's weak implementation techniques were forced into standard, and
your generation simply takes that as a religion.

Regards.

David W

unread,
Jan 14, 2007, 5:17:49 PM1/14/07
to
"Zorro" <zor...@comcast.net> wrote in message
news:1168807185.7...@m58g2000cwm.googlegroups.com...

>
> Simon G Best wrote:
> >
> > As usual, C++ does not impose safety on the programmer; instead, it
> > provides tools to help the programmer write safe code.
> >
> > :-)
> >
> > --
> > Simon G Best
> > What happens if I mention Leader Kibo in my .signature?
>
> Thanks to all comments, and in particular yours (to my blogger) I
> realized I had made a slieght error because multiple compilers gave me
> the same result (on Windows). My apologies. However ...
>
> I have redone the blogger, and the article to show the disadvantages of
> C++ exception model, and a better way of doing things. Looking at your
> comment (above) I do not see what you are really trying to say. What do
> you mean by "C++ does not impose safety on the programmer". So, how
> come you cannot call a private method?

Different kind of safety. Calling a private function wouldn't necessarily be
unsafe, at least not _because_ the function is private. OTOH, you can happily
dereference uninitialized pointers and other unsafe things.

> It is the purpose of a modern
> language to help with the safety.

Different languages have different goals. One of C++'s is to have minimal
overhead. If C++ doesn't suit your purpose, then choose another language.

> Then you say "C++ provides tools ....". Does C not do that already? So
> why use C++?

What do tools have to do with whether to use C or C++, given the vast array of
differences between the two languages?

DW


Zorro

unread,
Jan 14, 2007, 6:44:40 PM1/14/07
to

David W wrote:

> What do tools have to do with whether to use C or C++, given the vast array of
> differences between the two languages?

At least I thought the term tool (in context) meant linguistic
constructs, not tools external to the language itself. Sorry about
that. The vast array of differences were intended to ease development,
and for the most part they do.

> Different languages have different goals. One of C++'s is to have minimal
> overhead. If C++ doesn't suit your purpose, then choose another language.

I believe, in this one case, we are simply talking about the usefulness
of the C++ exception model. Is it really due to the significant
efficiency that C++ provides, that there is no resumption, for
instance. Or perhaps it has something to do with a form of
implementation that has been accepted as standard?

> Different kind of safety. Calling a private function wouldn't necessarily be
> unsafe, at least not _because_ the function is private. OTOH, you can happily
> dereference uninitialized pointers and other unsafe things.

No language can ever be completely safe. The intent is to move towards
a safer language, just as the introduction of "class" made a better C.
So now, all I am saying about C++ exception is that, it was not
well-thought. There is no need to change to a different language. The
standard can take a closer look and re-evaluate the benefits of the
current model. At least we can point out to other ideas by citing other
languages. One can close his ears to any argument by continually
bringing up "overhead". So be it.

Thanks for your comments.

Regards.

Alf P. Steinbach

unread,
Jan 14, 2007, 8:01:42 PM1/14/07
to
* Zorro:

> Is it really due to the significant
> efficiency that C++ provides, that there is no resumption, for
> instance. Or perhaps it has something to do with a form of
> implementation that has been accepted as standard?

Rather it's about safety. Microsoft wanted resumption, but didn't
manage to convince any others (IIRC). Mostly the idea of correcting and
resuming at the C++ or machine code instruction level is just Wrong;
however, it is a valid option at the block or function level, like the
exception handling in Eiffel, a retry of some higher level instead of
resumption. To emulate the Eiffel exception handling in C++ you can use
the template pattern (which has nothing to do with C++ templates, look
it up if you haven't heard about it). It would of course be more
practical & useful if C++ had closures...

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Zorro

unread,
Jan 14, 2007, 8:33:02 PM1/14/07
to

Thank you for your comment. If I go over everything you have packed in
one paragraph, this will go on forever. Just one point: MS has hardly
cared about convincing others to do what it wants to do. Otherwise it
would comply with the standard.

I am not, in any way, trying to extend the points you have made to a
lengthy discussion. Thanks again.

Regards.

Ian Collins

unread,
Jan 14, 2007, 9:14:16 PM1/14/07
to
Zorro wrote:

> David W wrote:
>>
>>Different languages have different goals. One of C++'s is to have minimal
>>overhead. If C++ doesn't suit your purpose, then choose another language.
>
>
> I believe, in this one case, we are simply talking about the usefulness
> of the C++ exception model. Is it really due to the significant
> efficiency that C++ provides, that there is no resumption, for
> instance. Or perhaps it has something to do with a form of
> implementation that has been accepted as standard?
>
The C++ exception model is designed for C++ generated exceptions, not
for asynchronous events generated form outside.

>
>>Different kind of safety. Calling a private function wouldn't necessarily be
>>unsafe, at least not _because_ the function is private. OTOH, you can happily
>>dereference uninitialized pointers and other unsafe things.
>
>
> No language can ever be completely safe. The intent is to move towards
> a safer language, just as the introduction of "class" made a better C.
> So now, all I am saying about C++ exception is that, it was not
> well-thought. There is no need to change to a different language. The
> standard can take a closer look and re-evaluate the benefits of the
> current model. At least we can point out to other ideas by citing other
> languages. One can close his ears to any argument by continually
> bringing up "overhead". So be it.
>
Overhead isn't the point at issue, differentiating between exceptions
thrown by the application and asynchronous events generated by the
operating environment is.

--
Ian Collins.

Julián Albo

unread,
Jan 14, 2007, 9:18:06 PM1/14/07
to
Zorro wrote:

> I believe, in this one case, we are simply talking about the usefulness
> of the C++ exception model. Is it really due to the significant
> efficiency that C++ provides, that there is no resumption, for
> instance. Or perhaps it has something to do with a form of
> implementation that has been accepted as standard?

You can read "The Design and Evolution of C++". It explains the rationale of
a bunch of design decisions.

--
Salu2

Zorro

unread,
Jan 14, 2007, 10:06:18 PM1/14/07
to

Thanks and regards.

Zorro

unread,
Jan 14, 2007, 10:07:37 PM1/14/07
to

Thank you.
Regards.

Zorro

unread,
Jan 15, 2007, 12:11:50 AM1/15/07
to

Mr. Best. I accidently went to the Z++ page in Wikipedia and saw your
interference. So I decided to reply to your comment, even though I wish
this thread to end immediately.

When you run the example that Ian did on Linux, you get "Arithmetic
Exception" and a crash. That means an exception was raised at a "level"
outside of scope of C++. Read my statement, and your comment to it
again to see if you are making any sense.

With all the respect, I am not interested in persuing this matter.
Regards.

Erik Wikström

unread,
Jan 15, 2007, 2:21:04 AM1/15/07
to
On Jan 14, 9:39 pm, "Zorro" <zor...@comcast.net> wrote:
> Simon G Best wrote:
>
> > As usual, C++ does not impose safety on the programmer; instead, it
> > provides tools to help the programmer write safe code.

> What do you mean by "C++ does not impose safety on the programmer".


> So, how come you cannot call a private method? It is the purpose of a
> modern language to help with the safety.
>
> Then you say "C++ provides tools ....". Does C not do that already? So
> why use C++?


C++ does not impose safety on the programmer by not requiring that the
safety-features are used, you can write very unsafe code in C++ if you
choose to. But C++ does provide features (such as private) that enables
the user to write safe code (these kind of things are the tools Simon
was referring to).

--
Erik Wikström

Grizlyk

unread,
Jan 15, 2007, 2:33:09 AM1/15/07
to
Simon G Best wrote:

> Grizlyk wrote:
> >
> > Can not, divide by zero can happen not only for zero, try divide 0xffff
> > to 0x02, test it in debug
>
> Interesting. Is that because, on your architecture, 0xFFFF is -0? (I'm
> just guessing.)

No, "divide by zero" can occure not only while you are dividing by 0,
in many cases, when CPU can not store result, that even can take more
memory, than source and divider have together.

Unsufficient memory can happends, when we are dividing very big number
to very small number ( due to CPU hardware limitations ), when divider
less than 1 (for floationg point) and 0 is just a limit of all here, as
most small number. Mathematically, to store result from 0 we need
memory of unlimited size.

> > But compiler easy can setup trap for the error and throw divide_by zero
> > exception.
>
> But we don't want the unnecessary overhead when there's no possibility
> of divide-by-zero. C++ leaves it to the programmer to decide whether or
> not checks are needed, rather than imposing such checks.

1. "Divide by zero" in most cases is error, for result is not the same,
as expect programmer. If it does not matter to him to get the concrete
result, why is he dividing? It is better to do addition - faster and
safe operation :)

2. We must report ALL errors to apropriate handler. Always. It is not
"overhead".

3. "Divide by zero" handled by CPU practicaly, already handled,
similarly "bad memory access". Do we throw in the cases or silently
call exit()?

Lets programmer make selection. To do it, standard must allow for
programmer to make selection between "throw" or "not throw".

Now C++ programmer can not throw easy, No one of way below is allowed
by standard:
a) check a std:: flag _divide_error
a/=b; if(std::_divide_error)throw bad_divide();
b) do automatic throw
try{ a/=b; }catch(...){}
and programmer can not do local selection of one of them.

4. Not only "Divide by zero", all processable harware errors must be
processed as point 3. I think.

> > It looks like " We do not want to process the error, and will try to
> > find a cause of it, if we will not find any, we will not process the
> > error also. Abtreten! " :)
>
> Sorry, I just didn't understand that. "try to find a cause of it"? "if
> we will not find any, we will not process the error also"?

Well,well:

try - verb, "to attempt to do any"
will try - future indefinite of try
to find - verb infinitive, "make a search of any"
will try to find - will try in order to find
a - "any kind of next noun"
cause - noun, "source of an action, root"
of - "cause of thunder" is "thunder cause"
it - you know what is "it"
and so on,

Ask if need more explanations :)

> > Speaking seriously, the ignoring the error as "undefined behaviour" may
> > be is not a best solution, because most CPUs can handle the error and
> > compilers must do good workaround (they do not do it itself), and if
> > CPU can not, the kind of C++ exception just will never appear.
>
> I didn't understand the second half of that. But as for "may be is not
> a best solution, because most CPUs can handle the error", the problem is
> that (as I understand it) the operating system deals with such things.

it is not easy for programmer, that OS will do anything with his error,
OS can not repair his program. Programmer want to restore after errors
and C++ exceptions one of the way to do it.

> Different operating systems deal with such things in different ways.

Yes, and C++ exceptions is one of the way to hide the differences.

> And, as I said above, such things are beyond the scope of the C++
> specification.

No, the question of safe and predictable excution is not beyond scope
of the C++, but bridge between "throw" and "CPU" of course beyond scope
of the C++.

> > I think, user can not effective manage the error, because can not jump
> > to hidden catch entry point directly, because trap can be executed in
> > other task(process) from which user can not throw, so user must do
> > unneccessary if-else after each divide operation, that is no good.
>
> Such checking only needs to be done in those cases where undefined
> behaviour would otherwise be possible, and would be unacceptable. Such
> checks don't need to be done for those cases where such undefined
> behaviour isn't able to occur anyway.

The "checks" already is being doing by CPU, you can not deny "checks"
and you must do not do something for "checks". If no errors accured -
no "checks" will happen.

> As usual, C++ does not impose safety on the programmer; instead, it
> provides tools to help the programmer write safe code.

In the case of "divide by zero" , we are speaking excactly about that
C++ does not provides tools to help the programmer write safe code. No
tools.

Andre Kostur

unread,
Jan 15, 2007, 2:32:16 AM1/15/07
to
"Zorro" <zor...@comcast.net> wrote in
news:1168837910.2...@q2g2000cwa.googlegroups.com:

>
> Simon G Best wrote:
>> Zorro wrote:
>> >
>> > Whether or not a raised exception is "thrown", the control from the
>> > try block makes a jump to the catch() section. That is what I meant
>> > by "catching none-thrown exceptions".
>>
>> Exceptions are raised *by throwing them.* In C++, that's what
>> raising an exception is. You can't have a raised exception that
>> isn't thrown, because you can't have a /thrown/ exception that isn't
>> thrown.
>

> Mr. Best. I accidently went to the Z++ page in Wikipedia and saw your
> interference. So I decided to reply to your comment, even though I
> wish this thread to end immediately.
>
> When you run the example that Ian did on Linux, you get "Arithmetic
> Exception" and a crash. That means an exception was raised at a
> "level" outside of scope of C++. Read my statement, and your comment
> to it again to see if you are making any sense.

However, you are confusing two different things. The "Arithmetic
Exception" is not an exception in the C++ sense of the word. If that error
message had read "Arithmetic FUBAR", would that help? Attempting to
"catch" this type of exception (directly) makes no sense at all.

> With all the respect, I am not interested in persuing this matter.

Usenet threads take on a life of their own... regardless of the
originator's wishes.

Kai-Uwe Bux

unread,
Jan 15, 2007, 3:32:51 AM1/15/07
to
Grizlyk wrote:

> Simon G Best wrote:
[snip]


>> As usual, C++ does not impose safety on the programmer; instead, it
>> provides tools to help the programmer write safe code.
>
> In the case of "divide by zero" , we are speaking excactly about that
> C++ does not provides tools to help the programmer write safe code. No
> tools.

That is not entirely correct: you can write a wrapper template for the
arithmetic types. I confine myself to a rough outline. Also, I will
acknowledge that it is impossible to make such wrappers behave exactly like
the built in types (e.g., with regard to automatic promotions and
conversions). However, in many cases, such a wrapper can be used. E.g., for
debugging pointers, I do use a smart pointer whose operator* method does
assert( underlying_pointer != 0 ).

#include <stdexcept>
#include <string>

struct divide_by_zero : public std::out_of_range {

divide_by_zero ( std::string const & msg )
: std::out_of_range( msg )
{}

}; // divide_by_zero

template < typename ArithmeticType >
struct throw_divide_by_zero {

typedef ArithmeticType base_type;

explicit
throw_divide_by_zero ( base_type x = 0 )
: data ( x )
{}

friend
throw_divide_by_zero operator+ ( throw_divide_by_zero lhs,
throw_divide_by_zero rhs ) {
return ( throw_divide_by_zero( lhs.data + rhs.data ) );
}

// many more friends
// ...

// and finally, division:

friend
throw_divide_by_zero operator/ ( throw_divide_by_zero lhs,
throw_divide_by_zero rhs ) {
if( rhs.data == 0 ) {
throw ( divide_by_zero( std::string( "division by 0" ) ) );
}
return ( throw_divide_by_zero( lhs.data + rhs.data ) );
}

private:

base_type data;

}; // throw_divide_by_zero

#include <iostream>

int main ( void ) {
try {
throw_divide_by_zero<int> a ( 0 );
throw_divide_by_zero<int> b ( 3 );
b / a;
}
catch ( divide_by_zero const & c ) {
std::cout << c.what() << '\n';
}
}


Best

Kai-Uwe Bux

Zorro

unread,
Jan 15, 2007, 4:24:11 AM1/15/07
to

Kai-Uwe, this is nice. However, look at all the code you have written
for something so simple. And you also expect everyone to remember how
to do such things in all cases, possibly in complex situations?

I am not entering the discussion. I was just wondering if you thought
about your extensive creativity.

Regards.

Zorro

unread,
Jan 15, 2007, 4:36:42 AM1/15/07
to

Erik, I am not sure where you disagree with me. I understand what Simon
means by tools. Then, I am saying that the use of those tools imposes
restrictions (if you will). A C++ programmer not using C++ features is
a human decision. The language cannot impose upon you to use it one way
or the other. Finally, I am saying that, C has sufficient features to
be used safely. The conclusion I am drawing is that, the reason for
something like private is so you can avoid mistakes in a large program.
I admit I made it very brief, but that is what I meant.

Regards.

Zorro

unread,
Jan 15, 2007, 5:09:45 AM1/15/07
to

Andre Kostur wrote:
> "Zorro" <zor...@comcast.net> wrote in
> news:1168837910.2...@q2g2000cwa.googlegroups.com:
>
> >
> > Simon G Best wrote:
> >> Zorro wrote:
> >> >
> >> > Whether or not a raised exception is "thrown", the control from the
> >> > try block makes a jump to the catch() section. That is what I meant
> >> > by "catching none-thrown exceptions".
> >>
> >> Exceptions are raised *by throwing them.* In C++, that's what
> >> raising an exception is. You can't have a raised exception that
> >> isn't thrown, because you can't have a /thrown/ exception that isn't
> >> thrown.
> >
> > Mr. Best. I accidently went to the Z++ page in Wikipedia and saw your
> > interference. So I decided to reply to your comment, even though I
> > wish this thread to end immediately.
> >
> > When you run the example that Ian did on Linux, you get "Arithmetic
> > Exception" and a crash. That means an exception was raised at a
> > "level" outside of scope of C++. Read my statement, and your comment
> > to it again to see if you are making any sense.
>
> However, you are confusing two different things. The "Arithmetic
> Exception" is not an exception in the C++ sense of the word. If that error
> message had read "Arithmetic FUBAR", would that help? Attempting to
> "catch" this type of exception (directly) makes no sense at all.
>

I did not say "Arithmetic Exception" is any form of C++ exception.
Please note what I am saying.

Exceptions occur at various levels of a system (CPU, layers of OS).
Each layer, either can handle the problem, or passes it to the next
layer. Now, if you wish to handle "Arithmetic Exception" in C++, you
need to throw it within C++. But whether you do, or do not throw the
exception in C++, somewhere in the system the exception will be raised.
It is an exception, and is not a FUBAR. Just because it was not thrown
within a C++ program does not change it to a FUBAR.

Requiring to throw exceptions that are expected to be caught is a
decision. It is not related to making or not making sense.

Hope this helps.

> > With all the respect, I am not interested in persuing this matter.
>
> Usenet threads take on a life of their own... regardless of the
> originator's wishes.

OK Andre. I must agree with you in that. Whether I can keep up with it
remains to be seen. Sometimes an incorrect use of a word (as it can
happen at this time of night) starts a whole new spark.

Regards.

Erik Wikström

unread,
Jan 15, 2007, 6:39:05 AM1/15/07
to
On Jan 15, 10:36 am, "Zorro" <zor...@comcast.net> wrote:
> Erik Wikström wrote:
> > On Jan 14, 9:39 pm, "Zorro" <zor...@comcast.net> wrote:
> > > Simon G Best wrote:
>
> > > > As usual, C++ does not impose safety on the programmer; instead, it
> > > > provides tools to help the programmer write safe code.
>
> > > What do you mean by "C++ does not impose safety on the programmer".
> > > So, how come you cannot call a private method? It is the purpose of a
> > > modern language to help with the safety.
>
> > > Then you say "C++ provides tools ....". Does C not do that already? So
> > > why use C++?
>
> > C++ does not impose safety on the programmer by not requiring that the
> > safety-features are used, you can write very unsafe code in C++ if you
> > choose to. But C++ does provide features (such as private) that enables
> > the user to write safe code (these kind of things are the tools Simon
> > was referring to).
>
> > --
> > Erik WikströmErik, I am not sure where you disagree with me. I understand what Simon

> means by tools. Then, I am saying that the use of those tools imposes
> restrictions (if you will). A C++ programmer not using C++ features is
> a human decision. The language cannot impose upon you to use it one way
> or the other. Finally, I am saying that, C has sufficient features to
> be used safely. The conclusion I am drawing is that, the reason for
> something like private is so you can avoid mistakes in a large program.
> I admit I made it very brief, but that is what I meant.

I was only giving an answer to the question 'What do you mean by "C++


does not impose safety on the programmer"'.

--
Erik Wikström

Erik Wikström

unread,
Jan 15, 2007, 6:47:34 AM1/15/07
to
On Jan 15, 8:33 am, "Grizlyk" <grizl...@yandex.ru> wrote:
> Simon G Best wrote:
> > Grizlyk wrote:
>
> > > Can not, divide by zero can happen not only for zero, try divide 0xffff
> > > to 0x02, test it in debug
>
> > Interesting. Is that because, on your architecture, 0xFFFF is -0? (I'm
> > just guessing.)
>
> No, "divide by zero" can occure not only while you are dividing by 0,
> in many cases, when CPU can not store result, that even can take more
> memory, than source and divider have together.
>
> Unsufficient memory can happends, when we are dividing very big number
> to very small number ( due to CPU hardware limitations ), when divider
> less than 1 (for floationg point) and 0 is just a limit of all here, as
> most small number. Mathematically, to store result from 0 we need
> memory of unlimited size.

Correct me if I'm wrong but is not this caused by the way floating
point arithmetic is performed? I seem to recall that first the numbers
are modified so that they have the same exponent, and while doing this
I suspect that the mantissa can become so small that it is rounded to
0, in which case the division will be by 0.

--
Erik Wikström

Gavin Deane

unread,
Jan 15, 2007, 7:24:15 AM1/15/07
to

Zorro wrote:

> Andre Kostur wrote:
> > However, you are confusing two different things. The "Arithmetic
> > Exception" is not an exception in the C++ sense of the word. If that error
> > message had read "Arithmetic FUBAR", would that help? Attempting to
> > "catch" this type of exception (directly) makes no sense at all.
> >
>
> I did not say "Arithmetic Exception" is any form of C++ exception.
> Please note what I am saying.
>
> Exceptions occur at various levels of a system (CPU, layers of OS).
> Each layer, either can handle the problem, or passes it to the next
> layer. Now, if you wish to handle "Arithmetic Exception" in C++, you
> need to throw it within C++. But whether you do, or do not throw the
> exception in C++, somewhere in the system the exception will be raised.
> It is an exception, and is not a FUBAR. Just because it was not thrown
> within a C++ program does not change it to a FUBAR.

Yes, it does. It seems to me reading this thread that your entire
question is based on coincidence. CPU designers have the concept of
what happens in awkward situations like divide by zero, and C++
programmers have the concept of what happens in responce to a throw
statement, and while those two concepts are utterly unrelated, both
groups of people (CPU designers and C++ programmers) happen to have
chosen the word "exception" to describe their concept.

If CPU designers had instead chosen the word "FUBAR" for their concept,
and C++ programmers had chosen the word "tadpole" for theirs, do you
really think your original question would have arisen?

Gavin Deane

Grizlyk

unread,
Jan 15, 2007, 9:13:10 AM1/15/07
to

Kai-Uwe Bux wrote:

> > Grizlyk wrote:
> > In the case of "divide by zero" , we are speaking excactly about that
> > C++ does not provides tools to help the programmer write safe code. No
> > tools.
>
> That is not entirely correct: you can write a wrapper template for the
> arithmetic types.

No, we can not write wrapper, because "divide by zero" error rising in
CPU, out of C++ scope.

1. C++ compiler can install low-level error handler, that will silently
ignore the error, but standard _do not require_ it.
2. C++ compiler can install low-level error handler, that will throw
(user can not generate throw from low-level error handler), but
standard _do not require_ it.
3. C++ compiler can install low-level error handler, that will set
errno (user sometimes can do it from low-level error handler), but
standard _do not require_ it.

In theory, compiler can generate exception even when overflow has
occured while addition operation. Let it is discussable.

But in the case of "divide by zero" very often is only way to handle
the error is terminating program, due to hardware unmaskable CPU rised
signal, not program rised. You can not write low-level handler for
concrete target system in order to continue execution.

So i think C++ standart at least must garantee, that no differences
will be for overflow at addition or divide operations (for example,
silently ignore errors or ignore & setup error flag).

Gavin Deane

unread,
Jan 15, 2007, 9:36:50 AM1/15/07
to

Grizlyk wrote:
> Kai-Uwe Bux wrote:
>
> > > Grizlyk wrote:
> > > In the case of "divide by zero" , we are speaking excactly about that
> > > C++ does not provides tools to help the programmer write safe code. No
> > > tools.
> >
> > That is not entirely correct: you can write a wrapper template for the
> > arithmetic types.
>
> No, we can not write wrapper, because "divide by zero" error rising in
> CPU, out of C++ scope.

Have you missed the point? In C++, the built in arithmetic types
provide no protection against divide-by-zero. If the code calls for
divide-by-zero, it will compile. What then happens at run-time is not
defined by the C++ stadard. But you snipped Kai-Uwe's code which showed
a wrapper template that included the following overloaded operator:

<quote>


friend
throw_divide_by_zero operator/ ( throw_divide_by_zero lhs,
throw_divide_by_zero rhs ) {
if( rhs.data == 0 ) {
throw ( divide_by_zero( std::string( "division by 0" ) ) );
}
return ( throw_divide_by_zero( lhs.data + rhs.data ) );
}

</quote>

I think the last line should actually have been
return ( throw_divide_by_zero( lhs.data / rhs.data ) );
Maybe a copy and paste error?

Anyway, using that template instead of built in arithmentic types, the
programmer is protected against divide-by-zero. If you try and divide
by zero, before you get to any use of the / operator on built in types,
the overloaded operator/ in Kai-Uwe's class detects the situation and
throws a C++ exception *INSTEAD OF* attempting to divide a built in
arithmetic type by zero.

Gavin Deane

Simon G Best

unread,
Jan 15, 2007, 12:59:50 PM1/15/07
to
Andre Kostur wrote:
>
> "Arithmetic FUBAR"

That fits very nicely with division-by-zero :-)

> Usenet threads take on a life of their own... regardless of the
> originator's wishes.

What can be said in the face of such truth.

Kai-Uwe Bux

unread,
Jan 15, 2007, 2:14:40 PM1/15/07
to
Zorro wrote:

If you have a need for this kind of thing, you write it once and the you
just use it. I do that for pointers. You do not need to re-implement that
every time. That's what library solutions are like.

Another advantage is the flexibility: if I regarded division by 0 a bug, I
could use an assert instead of a throw. I could even make that a policy
passed as a template parameter. If you put a mechanism into the core
language, you have a "one-size-fits-all" approach.


> I am not entering the discussion.

We shall see about that. It appears a though you might have something to
say.


> I was just wondering if you thought about your extensive creativity.

There is nothing extensive about the creativity in the code sample shown
above. The problem is fairly straight forward: the built-in types of C++
make virtually no guarantees towards enforcing preconditions of operations.
Thus, if you need types that do, you have to provide them yourself. That is
where the extensible type system of C++ comes in as the tool that the
language provides to help with these issues.

Other languages are designed differently. They may provide different means
of writing safe code. It is, however, not fair to claim that C++ does not
provide tools/mechanisms to ease safe coding.


Best

Kai-Uwe Bux

Simon G Best

unread,
Jan 15, 2007, 4:36:58 PM1/15/07
to
Zorro wrote:
>
> Thanks to all comments, and in particular yours (to my blogger) I
> realized I had made a slieght error because multiple compilers gave me
> the same result (on Windows). My apologies. However ...

:-)

> I have redone the blogger, and the article to show the disadvantages of
> C++ exception model, and a better way of doing things. Looking at your
> comment (above) I do not see what you are really trying to say. What do
> you mean by "C++ does not impose safety on the programmer". So, how
> come you cannot call a private method? It is the purpose of a modern
> language to help with the safety.

The programmer is not obliged to use the private: label. The programmer
could define classes as structs, and leave everything public, for
example. C++ does not impose privacy, but provides it as a tool that
the programmer can use to discourage (quite possibly unsafe) breaches of
intended encapsulation. So, actually, private: is a very good example
of how C++ provides tools for safety without imposing safety.

> Now, reread the article, without prejudice. I love C++ and I have known
> it from the time before it was called C++. My argument is that,
> someone's weak implementation techniques were forced into standard, and
> your generation simply takes that as a religion.

You still don't seem to understand C++ :-(

IR

unread,
Jan 15, 2007, 5:24:12 PM1/15/07
to
Zorro wrote:
> Kai-Uwe, this is nice. However, look at all the code you have
> written for something so simple.


There is one thing to keep in mind IMHO: C++ was designed to be a
_portable_ _systems_ language.

Even though it is close to the metal, it has to be the least common
denominator of all architectures it is intended to run on. Platform-
specific CPU exceptions clearly are not part of this "least common
denominator".

And no, handling a platform-specific exceptions like a division by
zero (or an access violation, for instance) is _not_ simple when you
consider that C++ can be implemented on platforms ranging from a 8-bit
68xx microcontroller up to the fastest supercomputers, with the x86
lying somewhere in the middle...

No wonder such a "trivial" task can take a few dozen lines to be
addressed correctly using only _standard_ C++...


Cheers,
--
IR

David W

unread,
Jan 15, 2007, 5:26:09 PM1/15/07
to
"Ian Collins" <ian-...@hotmail.com> wrote in message
news:5106boF...@mid.individual.net...

> Zorro wrote:
> >
> > No language can ever be completely safe. The intent is to move towards
> > a safer language, just as the introduction of "class" made a better C.
> > So now, all I am saying about C++ exception is that, it was not
> > well-thought. There is no need to change to a different language. The
> > standard can take a closer look and re-evaluate the benefits of the
> > current model. At least we can point out to other ideas by citing other
> > languages. One can close his ears to any argument by continually
> > bringing up "overhead". So be it.
> >
> Overhead isn't the point at issue, differentiating between exceptions
> thrown by the application and asynchronous events generated by the
> operating environment is.

Overhead has some relevance here, since you could replace such events with
exceptions. I presume that the reason that division by zero, for example,
produces undefined behaviour rather than a guaranteed C++ exception is the
checking overhead that would be necessary to throw an exception. If I have a
tight loop that does nothing but divisions and my code ensures that a division
by zero will not occur, I do not want superfluous checking for zero before every
division. Zorro wants the language to be safer, but the cost of that safety is
more than programnmers would be willing to bear. Many people choose to use C or
C++ precisely because they are "close to the machine" and in most cases do no
more than the programmer asks.

DW


IR

unread,
Jan 15, 2007, 5:37:59 PM1/15/07
to
David W wrote:
> Overhead has some relevance here, since you could replace such
> events with exceptions. I presume that the reason that division by
> zero, for example, produces undefined behaviour rather than a
> guaranteed C++ exception is the checking overhead that would be
> necessary to throw an exception.

As a side note, all platforms I have worked on use some kind of IRQ to
notify the system when such event occurs, so it has no runtime cost in
"normal" operation in such cases.

But I agree that it is different on some architectures, and that this
may be the very reason why the C++ standard considers CPU-specific
exceptions as UB.


Cheers,
--
IR

Simon G Best

unread,
Jan 15, 2007, 7:11:28 PM1/15/07
to
IR wrote:
>
> As a side note, all platforms I have worked on use some kind of IRQ to
> notify the system when such event occurs, so it has no runtime cost in
> "normal" operation in such cases.

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.

:-|

Simon G Best

unread,
Jan 15, 2007, 7:46:00 PM1/15/07
to
Grizlyk wrote:
> Simon G Best wrote:
>
>> Grizlyk wrote:
>>> Can not, divide by zero can happen not only for zero, try divide 0xffff
>>> to 0x02, test it in debug
>> Interesting. Is that because, on your architecture, 0xFFFF is -0? (I'm
>> just guessing.)
>
> No, "divide by zero" can occure not only while you are dividing by 0,
> in many cases, when CPU can not store result, that even can take more
> memory, than source and divider have together.
>
> Unsufficient memory can happends, when we are dividing very big number
> to very small number ( due to CPU hardware limitations ), when divider
> less than 1 (for floationg point) and 0 is just a limit of all here, as
> most small number. Mathematically, to store result from 0 we need
> memory of unlimited size.

Are you talking about arithmetic overflow, and the like? I'm still not
sure quite what you meant by "divide 0xffff to 0x02", but I had thought
you meant integer division.

>>> But compiler easy can setup trap for the error and throw divide_by zero
>>> exception.
>> But we don't want the unnecessary overhead when there's no possibility
>> of divide-by-zero. C++ leaves it to the programmer to decide whether or
>> not checks are needed, rather than imposing such checks.
>
> 1. "Divide by zero" in most cases is error, for result is not the same,
> as expect programmer. If it does not matter to him to get the concrete
> result, why is he dividing? It is better to do addition - faster and
> safe operation :)

Divide-by-zero isn't always a possibility. Such errors don't always
have the possibility of occurring. Consider the following:-

int foo(int x) {
for (int i(1); i <= 10; ++i) // i can't ever be zero.
x /= i; // Can never be divide-by-zero.
return x;
}

Checking for divide-by-zero, or checking for such things as system-level
(non-C++) 'exceptions', would be needless overhead in such a function.

> 2. We must report ALL errors to apropriate handler. Always. It is not
> "overhead".

It's needless overhead when there's no possibility of such errors occuring.

> 3. "Divide by zero" handled by CPU practicaly, already handled,
> similarly "bad memory access". Do we throw in the cases or silently
> call exit()?

No. Usually, the operating system will handle such events. How the
operating system handles them depends on the operating system itself -
and that's beyond the scope of the C++ standard, because it's outside
the C++ language. There are various ways in which an operating system
could respond to such an event. Some may just terminate the process
that caused the event - the process gets no say in the matter at all.
Some may send some sort of signal to the process - but that signal may
be asynchronous. There are other possibilities.

For a process to deal with all such events the way you want, it would
have to pre-empt such events on some systems (with overheads), check for
corresponding signals on some other systems (with overheads), and do
other stuff on yet other systems (which again may involve overheads).
Such overheads only make sense when there's a real possibility of such
events occurring, and when such events would need to be handled
properly. Having such overheads each and every time certain kinds of
operations get performed, 'just in case', would result in needless
overheads on those occasions when such operations can't possibly cause
such events anyway.

Instead, as usual, C++ lets the programmer decide whether or not such
overheads are needed, rather than imposing them on the programmer.

> Lets programmer make selection. To do it, standard must allow for
> programmer to make selection between "throw" or "not throw".

Indeed. That's what C++ does.

> Now C++ programmer can not throw easy, No one of way below is allowed
> by standard:
> a) check a std:: flag _divide_error
> a/=b; if(std::_divide_error)throw bad_divide();
> b) do automatic throw
> try{ a/=b; }catch(...){}
> and programmer can not do local selection of one of them.

What C++ does is it allows the following (if I remember the relevant
syntax correctly):-

// I'm assuming int a, b;.
try {
if (b == 0) throw bad_divide();
a /= b;
} catch(...) { /*...*/ }

That's nicely platform-independent and portable :-) Also, in those
cases where there's no possibility of divide-by-zero, the try-catch
stuff need not be included, as bad_divide() will never get thrown, and
there'll never be anything to catch - no needless overheads.

> 4. Not only "Divide by zero", all processable harware errors must be
> processed as point 3. I think.

Does that include an asteroid, a Cheeky Girl, or Lembit Opik landing
abruptly on the computer?

>>> It looks like " We do not want to process the error, and will try to
>>> find a cause of it, if we will not find any, we will not process the
>>> error also. Abtreten! " :)
>> Sorry, I just didn't understand that. "try to find a cause of it"? "if
>> we will not find any, we will not process the error also"?
>
> Well,well:
>
> try - verb, "to attempt to do any"
> will try - future indefinite of try
> to find - verb infinitive, "make a search of any"
> will try to find - will try in order to find
> a - "any kind of next noun"
> cause - noun, "source of an action, root"
> of - "cause of thunder" is "thunder cause"
> it - you know what is "it"
> and so on,

I understood the words :-) but not what you meant.

>> Different operating systems deal with such things in different ways.
>
> Yes, and C++ exceptions is one of the way to hide the differences.

Yes, indeed :-)

>> And, as I said above, such things are beyond the scope of the C++
>> specification.
>
> No, the question of safe and predictable excution is not beyond scope
> of the C++, but bridge between "throw" and "CPU" of course beyond scope
> of the C++.

Uh, yeah, I think :-)

>> As usual, C++ does not impose safety on the programmer; instead, it
>> provides tools to help the programmer write safe code.
>
> In the case of "divide by zero" , we are speaking excactly about that
> C++ does not provides tools to help the programmer write safe code. No
> tools.

The tools are there, but the programmer has to use them (as illustrated
above).

Simon G Best

unread,
Jan 15, 2007, 7:49:00 PM1/15/07
to
Grizlyk wrote:
> Kai-Uwe Bux wrote:
>
>>> Grizlyk wrote:
>>> In the case of "divide by zero" , we are speaking excactly about that
>>> C++ does not provides tools to help the programmer write safe code. No
>>> tools.
>> That is not entirely correct: you can write a wrapper template for the
>> arithmetic types.
>
> No, we can not write wrapper, because "divide by zero" error rising in
> CPU, out of C++ scope.

What you do is you pre-empt such divisions by zero from even occurring
in the first place. That's the sort of thing that the suggested
wrappers do. No need to handle signals (or whatever) from lower down.

Zorro

unread,
Jan 15, 2007, 11:24:44 PM1/15/07
to

Comments starting with David, IR and here Simon are all valid and quite
interesting. The focal point is made by Simon, that the run-time lib of
language must have some form of check, for instance, is a flag set
(This can be done efficiently, and is not as bad as it sounds).
However, the model that results from having run-time support is
interesting too. As statements are executed, should an exception occur,
there is no need to write a statement such as throw for it. Note that,
I did not say system exception, or exceptions defined by user, or
whatever. Generally, of course, a user will define exceptional states
unknown to the libraries, and must explicitly raise those exceptions
(do a throw). Nevertheless, there are always an array of well-known
exceptions that the libraries can support. That is where the price is
paid. Do we want the run-time to check, or do we want the compiler to
take charge in all cases. When we leave it to the compiler
(synchronous), run-time library will generally not need to be aware of
exceptions occuring below it because the system will abort it.
Without support from run-time libs, I do not believe there is a way to
support resumption.
So, one has to accept a language for its purpose. As pointed out in
your notes, C and C++ are system programming languages, and one expects
them to be efficient.

I hope this helps, and that I have not said something against C++.
Regards.

Zorro

unread,
Jan 15, 2007, 11:27:45 PM1/15/07
to

My apologies for the misunderstanding on my part.
Regards.

Zorro

unread,
Jan 15, 2007, 11:38:25 PM1/15/07
to

I do, but I really meant what I said. This will take a long discussion.

>
> > I was just wondering if you thought about your extensive creativity.
>
> There is nothing extensive about the creativity in the code sample shown
> above. The problem is fairly straight forward: the built-in types of C++
> make virtually no guarantees towards enforcing preconditions of operations.
> Thus, if you need types that do, you have to provide them yourself. That is
> where the extensible type system of C++ comes in as the tool that the
> language provides to help with these issues.
>
> Other languages are designed differently. They may provide different means
> of writing safe code. It is, however, not fair to claim that C++ does not
> provide tools/mechanisms to ease safe coding.
>

Perhaps more like "it can become better" as in future revisions of the
standard. In other words, the point of discussion is what else can be
done, rather than putting down C++. I doubt the current standard is end
of evolution for C++.

Regards.

>
> Best
>
> Kai-Uwe Bux

Zorro

unread,
Jan 15, 2007, 11:41:38 PM1/15/07
to

This is a very good point.
Regards.

Zorro

unread,
Jan 16, 2007, 12:25:00 AM1/16/07
to

Gavin, the original question was the result of an error. I have
apologized for that. I further appreciate the comments that stopped me
from making a bigger fool of myself by inferring from the behavior of
C++ compilers on a single operating system. The article was redone as a
result, thanks everyone.

About the term "exception", the CPU simply sets a bit (say the overflow
bit in an addition). Depending on the context, the operating system may
or may not consider the instruction as invalid. If it does, it will
raise what has become known as exception. That was done by programmers,
who at the time had to use assembly language (I have done a lot of it),
later C and now C++.

The issue really never was "division-by-zero". It was the jump made to
the catch point without a throw, and resulting in destructors not being
called. I was wrong in that, this had nothing to do with C++ standard.

As comments were made, I replied the best way I could to end the topic.
But it has taken its own life, as pointed out by one of the authors.
For instance, I had to say something about your comment, and I am
trying to stay out of what could take a long discussion.

Regards.

Grizlyk

unread,
Jan 16, 2007, 2:24:57 AM1/16/07
to
Gavin Deane wrote:

> > Grizlyk wrote:
> > No, we can not write wrapper, because "divide by zero" error rising in
> > CPU, out of C++ scope.
>

> Have you missed the point? In C++, the built in arithmetic types
> provide no protection against divide-by-zero.

Yes, you aree with me, that C++ does not provide any protection against
divide-by-zero. The couse of it
1. snow in California in 2004 year,
2. mongol invasion,
3. erathquake on Mars,
or something else
it does not matter for us, because we must write low-level error
handler for unknown target machine with C++ compiler, because C++ does
not do it for us.
No? see below.

> But you snipped Kai-Uwe's code which showed
> a wrapper template that included the following overloaded operator:
>
> <quote>

> friend
> throw_divide_by_zero operator/ ( throw_divide_by_zero lhs,
> throw_divide_by_zero rhs ) {
> if( rhs.data == 0 ) {
> throw ( divide_by_zero( std::string( "division by 0" ) ) );
> }
> return ( throw_divide_by_zero( lhs.data + rhs.data ) );
> }

> </quote>

> if( rhs.data == 0 )

I am repeating again - source of the exception is hardware (CPU), the
test (rhs.data == 0) _is not enough_.

> lhs.data + rhs.data
Means ( lhs.data / rhs.data ) - do you want to divide without CPU?

In general, you need another special CPU or coprocessor in your system,
which will not generate "divide by zero" to use your wrapper.

Grizlyk

unread,
Jan 16, 2007, 2:29:08 AM1/16/07
to

Grizlyk

unread,
Jan 16, 2007, 3:06:12 AM1/16/07
to

Simon G Best wrote:

And this is answer for you too:

http://groups.google.com/group/comp.lang.c++/tree/browse_frm/thread/787927fea68e3882/1187c67153b5cb46?#doc_13940264e5e65ae9

> Are you talking about arithmetic overflow, and the like? I'm still not
> sure quite what you meant by "divide 0xffff to 0x02", but I had thought
> you meant integer division.

Just write any file and post it to debug as I wrote or read any book
about ix86 asm and DIV opcode. When we are dividing short numbers, C++
compiler can extend operands to ensure, the only 0 gives the error, but
resorces of the CPU (or other CPU) is not unlimited.

> > 1. "Divide by zero" in most cases is error, for result is not the same,
> > as expect programmer.
>

> Divide-by-zero isn't always a possibility. Such errors don't always
> have the possibility of occurring. Consider the following:-
>

> Checking for divide-by-zero, or checking for such things as system-level
> (non-C++) 'exceptions', would be needless overhead in such a function.

I can not understand metter of your objections and why "needless
overhead" will appear.

> > 2. We must report ALL errors to apropriate handler. Always. It is not
> > "overhead".
>
> It's needless overhead when there's no possibility of such errors occuring.

I can not understand metter of your objections and why reporting about
error is "needless overhead", especially if error checking is hardware.


> > 3. "Divide by zero" handled by CPU practicaly, already handled,
> > similarly "bad memory access". Do we throw in the cases or silently
> > call exit()?
>
> No. Usually, the operating system will handle such events.

No of course, OS can only protect other parts of system, from you and
your program, OS _can not_ resume your program after error. It is
evidently.

C language proposes "signals" mechanism as std library, but it is not
enough for C++ and does not garantee any except halt by error. I think.

> How the
> operating system handles them depends on the operating system itself -
> and that's beyond the scope of the C++ standard, because it's outside
> the C++ language.

"How the operating system handles" is really out of C++, but "how you
program will continue" is not, is not out of C++.

> > Lets programmer make selection. To do it, standard must allow for
> > programmer to make selection between "throw" or "not throw".
>
> Indeed. That's what C++ does.

No, does not, because C++ had no std tools to control it.

>
> > Now C++ programmer can not throw easy, No one of way below is allowed
> > by standard:
> > a) check a std:: flag _divide_error
> > a/=b; if(std::_divide_error)throw bad_divide();
> > b) do automatic throw
> > try{ a/=b; }catch(...){}
> > and programmer can not do local selection of one of them.
>

> try {
> if (b == 0) throw bad_divide();

"(b == 0)" is not enough to prevent "divide by zero" error.

> That's nicely platform-independent and portable :-)

No

> > 4. Not only "Divide by zero", all processable harware errors must be
> > processed as point 3. I think.
>
> Does that include an asteroid, a Cheeky Girl, or Lembit Opik landing
> abruptly on the computer?

What is "Cheeky Girl" or "Lembit Opik" or "abruptly" in other places?

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.

> I understood the words :-) but not what you meant.

This is allegory.

Ian Collins

unread,
Jan 16, 2007, 3:20:25 AM1/16/07
to
Grizlyk wrote:
> Simon G Best wrote:
>
>>How the
>>operating system handles them depends on the operating system itself -
>>and that's beyond the scope of the C++ standard, because it's outside
>>the C++ language.
>
There's nothing an application can do if the operating environment
terminates it.

>
> "How the operating system handles" is really out of C++, but "how you
> program will continue" is not, is not out of C++.
>
>>>Lets programmer make selection. To do it, standard must allow for
>>>programmer to make selection between "throw" or "not throw".
>>
>>Indeed. That's what C++ does.
>
> No, does not, because C++ had no std tools to control it.
>
You can't have standard tools to control something the application
cannot control.

--
Ian Collins.

Kai-Uwe Bux

unread,
Jan 16, 2007, 3:34:53 AM1/16/07
to
Grizlyk wrote:

For integral types, the c++ standard guarantees that this test is enough:
division by any integer different from 0 is guaranteed to produce an
(implementation defined) result. For floating point arithmetic, life may be
harder.

>> lhs.data + rhs.data
> Means ( lhs.data / rhs.data ) - do you want to divide without CPU?

Again, for integer types, the above line is guaranteed to work by the
standard provided rhs.data is a legal value != 0.

> In general, you need another special CPU or coprocessor in your system,
> which will not generate "divide by zero" to use your wrapper.

No you don't. All you need is a standard compliant compiler. Should the CPU
do something funny when you divide 10 by 3 the compiler would have to work
around this in order to be standard compliant.

I concede that (depending on the platform) there can be bit patterns that do
not represent legal values for signed integer types. You just have to write
the wrapper class so that it guarantees as an invariant that the underlying
integer data will never be invalid. This will require adding overflow
detection for +,-, and *. For unsigned integer types, all bit patterns are
valid values and these measures are unnecessary.


Best

Kai-Uwe Bux

Grizlyk

unread,
Jan 16, 2007, 4:00:08 AM1/16/07
to
Ian Collins wrote:

> There's nothing an application can do if the operating environment
> terminates it.

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.

If OS will terminate process on overflow, it is concrete OS problem, as
DOS has no native threads suport, for example.

> > No, does not, because C++ had no std tools to control it.
> >
> You can't have standard tools to control something the application
> cannot control.

Application can control.

Bjoern Doebel

unread,
Jan 16, 2007, 4:47:26 AM1/16/07
to
Grizlyk wrote:
> Ian Collins wrote:
>
>> There's nothing an application can do if the operating environment
>> terminates it.
>
> 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

It is loading more messages.
0 new messages