assert and enforce both compiled out with -release

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sat Jan 27 16:19:30 UTC 2018


On Saturday, January 27, 2018 14:59:50 kdevel via Digitalmars-d-learn wrote:
> On Saturday, 27 January 2018 at 14:51:23 UTC, Ali Çehreli wrote:
> > On 01/27/2018 06:36 AM, kdevel wrote:
> >> On Saturday, 27 January 2018 at 14:31:13 UTC, Ali Çehreli
> >>
> >> wrote:
> >>> > But assert is also ignored in release mode:
> >>> The documentation is not clear. "they will be compiled out"
> >>> means "contracts are compiled out". So, an enforce() would
> >>> disappear if it's inside such a block, which should not be
> >>> what the programmer wants for an enforce().
> >>
> >> The documentation was clear as glass (but wrong): "Use assert
> >> in contracts."
> >>
> >>> Fixed it through the "Improve this page" link on that Phobos
> >>> page:
> >>>
> >>>   https://github.com/dlang/phobos/blob/master/std/exception.d
> >>
> >> "Use $(D assert) in contracts." is still in there.
> >
> > What's wrong with that? What documentation is trying to say is
> > "do not use enforce in contracts; use assert in contracts" and
> > that's exactly the idea.
>
> I can't see a problem which would be solved by following this
> advice. It distracts the reader (me) from gettin his (my) work
> done. If I compile not for release both, enforce and assert, are
> in effect. If I compile for release both, enforce and assert, are
> disabled. So by replacing enforce with assert I gain nothing.

No, enforce is _not_ disabled with -release. e.g.

void foo(int i)
{
    enforce(i > 42);
}

void main()
{
    foo(0);
}

will throw an exception even when you compile with -release. The problem is
that you're using enforce inside a contract instead of inside the function's
body.

Contracts are specifically for asserting pre and post conditions. It is
expected that they only be used for assertions or for code which is going to
be run in preparation for running an assertion. They are _not_ for code
which is intended to be part of the final program, and they are compiled out
with -release, just like assertions are compiled out elsewhere in the code.
As such, any code in a contract - be it an assertion, a call to enforce, or
any arbitarily complex piece of code - will not be in the final program.

Anything that you want in your final program should not be in a contract. If
you want to use exceptions - be it with enforce or with an if statement and
explicitly throwing - then don't put them in any contracts. They _will_ get
compiled out. As such, it makes no sense to use enforce in a contract. It
should go in the function body.

- Jonathan M Davis




More information about the Digitalmars-d-learn mailing list