strange behavior of by-value function arguments in postcondition

bauss jj_1337 at live.dk
Fri Sep 3 06:25:44 UTC 2021


On Thursday, 2 September 2021 at 13:33:34 UTC, Meta wrote:
> On Wednesday, 1 September 2021 at 06:14:27 UTC, bauss wrote:
>> Pre/post conditions _are_ assert statements tho. User 
>> validation should be done using exceptions, not asserts.
>
> The fact that they are assert statements is an implementation 
> detail. The point of pre/post conditions is to enforce that 
> certain properties of the function hold, and assertions are 
> just how the language happens to implement that.

I would argue that they're there to enforce certain properties of 
the function to hold true when testing, because you should use 
exceptions otherwise!

D's error handling is primarily exceptions and asserts should 
never be used for error handling because they shouldn't be in 
release builds and AFAIK release builds remove them.

So if you're writing a library and compiling it for release and 
it takes user-input then the validation will never occur.

It's evident in this:

Compile this with the -release switch:

```d
import std;

void a(int x) in (x > 10) { writeln(x); }

void main()
{
     a(12);
     a(5);
}
```

You'll see that a(5) will succeed, so the output is:

12
5

However without -release it will be this:

12
core.exception.AssertError at onlineapp.d(3): Assertion failure
----------------
??:? _d_assertp [0x55b9b3fe87fc]
./onlineapp.d:3 void onlineapp.a(int) [0x55b9b3fe6edf]
./onlineapp.d:8 _Dmain [0x55b9b3fe6f03]

The solution here is actually to use exceptions if going by 
idiomatic D:

void a(int x) in (x > 10) { if (x < 10) throw new 
Exception(x.stringof ~ " is below 10."); writeln(x); }

Now regardless of whether you're debugging or publishing it will 
give an error.

Debugging output is the same as before, but -release will now 
output:

12
object.Exception at onlineapp.d(3): x is below 10.
----------------
./onlineapp.d:3 void onlineapp.a(int) [0x5635e7a70df4]
./onlineapp.d:8 _Dmain [0x5635e7a70e1b]

Imagine if x came from an external source, you'd NEED to have 
some runtime validation at release and not assume everything 
works during tests/debugging.

You'll end up with either silent errors that are hard to debug OR 
you'll end up with tons of crashes with no clear indication.


More information about the Digitalmars-d mailing list