Reputation: 190809
In the course of asking about catching 'divide by 0' exception, I found that with C++, we can't do that. I mean, divide by 0 doesn't throw an std::exception.
Some of the hints that I found were I have to check the value, and throw the exception by self.
I say it's confusing, as I've thought that C++ adopted the exception idea in order to replace the 'good old C/UNIX report error by returning value method'.
Here are my questions
Upvotes: 7
Views: 774
Reputation: 490148
Upvotes: 1
Reputation: 2029
About Q3 - exceptions are something which should occure exceptional :) So to avoid (which is possible with div0) is always better. Additionally to Emyr (who is right about "avoid wasted cycles for calculation") you should consider that throwing an exception means a lot of "internal work" since the context changes (you may leave loop, functions, instance methods....) and your "excpetion stack" has to be prepared.
So in general exception handling is "the common method" to handle exceptions. But it should not be a pattern to avoid "value checking".
if(!string.IsNullOrEmpty(....) ... is much better than try{ xx=MyMabeNullString.Length... } catch{ //errmess - I could have checked it before :) }
Upvotes: 1
Reputation: 146930
C++ doesn't use a lot of good principles in some places in order to maintain compatibility with C code. Java and such has no such constraints, so they can do what they'd like.
In C++, always throw an exception. But, for something like divide by zero, you really should just check it yourself. It's not an exceptional circumstance, it's you failing to check yourself.
Upvotes: 1
Reputation: 10562
1) Throwing exceptions is an expensive operation. The C++ philosophy is not to pay for what you don't use. If you want exceptions, you throw them yourself (or use libraries that do).
2) Never accept the divide by zero error. It depends on the situation, if you know the input will never be a 0 never check for it. If you are unsure, always check for it. Then either throw an exception, or swallow the error quietly. It is up to you.
3) Exception throwing, especially combined with RAII can make for truely elegant and beautiful code. This may not be acceptable in all situations. You may have 100% confidence in your inputs and wish for raw performance. If you are creating a DLL you do not really want to be throwing exceptions out of your api, but for a critically consistant statically linked library you would be advised to.
Upvotes: 2
Reputation: 791909
C++ is implemented on many different platforms and is designed to support high-performance applications. Allowing undefined behaviour means than not all uses of division need to be burdened by extra checking and a possible exception throw by the compiler. The compiler is allowed to implement the fastest translation of divide in machine code regardless of its behaviour on divide by zero.
As with performing any operation, it is the programmers responsibility to ensure that any pre-conditions are met. In the case of division, a programmer may know that the divisor cannot be zero (or very small) and may just use an assert; in other cases he might need to validate the input and throw an application specific exception if the conditions aren't met.
C++ isn't (just) an OO language and doesn't (in most cases) enforce the use of exceptions. It provides them as a tool for use where appropriate. There are other languages which force the use of exceptions to a much greater degree.
Upvotes: 2
Reputation: 503893
C++ assumes you know what you're doing, doesn't pay for things you don't ask for, and makes no assumptions about the platforms it's intended for.
If you want to divide numbers, it would be quite inefficient to mandate the compiler check the denominator and throw before dividing. (We didn't ask it to do that.) So that option is out; we can't have this check on every division, and it's especially wasteful since most divisions are not by zero.
So, how can we just divide by zero and find out if it worked? Because C++ cannot assume anything about it's platform, it cannot assume there is a way to check the result, hardware-wise. That is to say, while many CPU's will jump to an interrupt of some sort when division by zero occurs, the C++ language cannot guarantee such a thing.
The only option then is to let the behavior be undefined. And that's exactly what you get: undefined behavior.
OOP languages might do something or another, it doesn't matter since OOP isn't well-defined and C++ isn't an OOP language anyway. In general, use the tool that's most appropriate. (Exceptions are for exceptional situations.)
Upvotes: 9
Reputation: 2371
Divide by zero is something you can test for before the calculating line, which could avoid wasted cycles if it's a complicated formula.
Upvotes: 1