I think all of the answers which explain that you should not have a flag that controls whether an exception is thrown or not are good. Their advice would be my advice to anyone who feels the need to ask that question.
I did, however, want to point out that there is a meaningful exception to this rule. Once you are advanced enough to start developing APIs that hundreds of other people will use, there are cases where you might want to provide such a flag. When you are writing an API, you're not just writing to the purists. You're writing to real customers who have real desires. Part of your job is to make them happy with your API. That becomes a social problem, rather than a programming problem, and sometimes social problems dictate solutions which would be less than ideal as programming solutions on their own.
You may find that you have two distinct users of your API, one of which wants exceptions and one that does not. A real life example where this could occur is with a library that is used both in development and on an embedded system. In development environments, users will likely want to have exceptions everywhere. Exceptions are very popular for handling unexpected situations. However, they are forbidden in many embedded situations because they're too hard to analyze real-time constraints around. When you actually care about not just the average time it takes to execute your function, but the time it takes for any one individual fun, the idea of unwinding the stack at any arbitrary place is very undesirable.
A real life example for me: a math library. If your math library has a Vector
class which supports getting a unit vector in the same direction, you have to be able to divide by the magnitude. If the magnitude is 0, you have a divide by zero situation. In development you want to catch these. You really don't want surprising divide by 0's hanging around. Throwing an exception is a very popular solution for this. It almost never happens (it is truly exceptional behavior), but when it does, you want to know it.
On the embedded platform, you don't want those exceptions. It would make more sense to do a check if (this->mag() == 0) return Vector(0, 0, 0);
. In fact, I see this in real code.
Now think from the perspective of a business. You can try to teach two different ways of using an API:
// Development version - exceptions // Embeded version - return 0s
Vector right = forward.cross(up); Vector right = forward.cross(up);
Vector localUp = right.cross(forward); Vector localUp = right.cross(forward);
Vector forwardHat = forward.unit(); Vector forwardHat = forward.tryUnit();
Vector rightHat = right.unit(); Vector rightHat = right.tryUnit();
Vector localUpHat = localUp.unit() Vector localUpHat = localUp.tryUnit();
This satisfies the opinions of most of the answers here, but from a company perspective this is undesirable. Embedded developers will have to learn one style of coding, and development developers will have to learn another. This can be rather pesky, and forces people into one way of thinking. Potentially worse: how do you go about proving that the embedded version doesn't include any exception throwing code? The throwing version can easily blend in, hiding somewhere in your code until an expensive Failure Review Board finds it.
If, on the other hand, you have a flag which turns on or off exception handling, both groups can learn the exact same style of coding. In fact, in many cases, you can even use one group's code in the other group's projects. In the case of this code using unit()
, if you actually care about what happens in a divide by 0 case, you should have written the test yourself. Thus, if you move it to an embedded system, where you just get bad results, that behavior is "sane." Now, from a business perspective, I train my coders once, and they use the same APIs and the same styles in all parts of my business.
In the vast majority of cases, you want to follow the advice of others: use idioms like tryGetUnit()
or similar for functions that don't throw exceptions, and instead return a sentinel value like null. If you think users may want to use both exception handling and non-exception handling code side by side within a single program, stick with the tryGetUnit()
notation. However, there is a corner case where the reality of business can make it better to use a flag. If you find yourself in that corner case, do not be afraid to toss the "rules" by the wayside. That's what rules are for!