prosseek
prosseek

Reputation: 190809

Error processing : return value vs exception in C++

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

Answers (7)

Jerry Coffin
Jerry Coffin

Reputation: 490148

  1. Because C++ is intended to be "close to the metal" and mostly tries to pass simple operations like division through to the hardware relatively directly (so if you can't depend on hardware to enforce a constraint, C++ probably won't by default either).
  2. I don't think there's a universal answer to that. Some C++ programmers write almost C-like code that almost never uses exception handling. Others use exception handling quite rigorously (and most are somewhere in between).
  3. While there's almost certainly a correlation between OO and exception handing, I don't think it's really cause and effect. The factors that seem likely to me are:
    1. OOP and exception handling tend to be most useful in similar (e.g., large) projects.
    2. OOP and exception handling have both become more common over time. Older OO languages often lack exception handling. Newer languages often have exception handling, even if they're not OO at all.

Upvotes: 1

ManniAT
ManniAT

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

Puppy
Puppy

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

DanDan
DanDan

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

CB Bailey
CB Bailey

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

GManNickG
GManNickG

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

Emyr
Emyr

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

Related Questions