spir wrote:
On 03/25/2011 11:20 PM, Jonathan M Davis wrote:
In the case of something like dividing by 0 or other math functions that could be given bad values, the typical solution is to either use an assertion (or check nothing) and then let the caller worry about it. It would be extremely wasteful to have to constantly check whether the arguments to typical math
functions are valid. They almost always are, and those types of functions
needto be really efficient.

But catching wrong arguments to math functions at *runtime* is precisely what D itself does (as well as all languages I know):

    auto a = 1, b = 0;
    auto c = a/b;
==>
    Floating point exception

There is no way out, or do I miss a point?

Denis

That one is done by the CPU, as mentioned in another post. But it does illustrate something interesting: the contract programming makes you think there is a symmetry between in and out contracts, whereas in fact they have very little in common. If an out contract fails, it ALWAYS indicates a bug in the function. So it should ALWAYS be an assert. But 'in' contracts are completely different, since they indicate a problem in the calling code. (Personally I cannot see the value of 'out' contracts, except as information for verifying later 'in' contracts).

When I started writing D code, I originally used 'in' contracts frequently in my mathematical code. But later, I removed most of them. Why? Because including a particular condition in a 'in' contract makes it undefined behaviour in release mode!

So you need to be clear, is this parameter value a runtime error, or is it a bug in the calling code? In most mathematical code, you want it to be an error -- you don't normally want undefined behaviour for particular inputs. If the requirements for valid parameter values are complicated, you're placing a huge burden on the caller if you include asserts, making them bugs.

In summary: enforce is nice for the caller, assert is nice for the callee.

The decision of whom to favour can be tricky.

Reply via email to