How to enforce compile time evaluation (and test if it was done at compile time)

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Mar 1 08:43:41 PST 2017


On Tuesday, February 28, 2017 09:16:47 sarn via Digitalmars-d-learn wrote:
> On Tuesday, 28 February 2017 at 07:41:36 UTC, Christian Köstlin
>
> wrote:
> > As I understand the only difference between assert and enforce
> > is, that
> > assert is not compiled into releases?
> >
> > Thanks!
> > Christian
>
> Pretty much so.  The intention is that assert means something
> that's supposed to be true (and can be assumed in release) while
> enforce means something you want to be true (but can't guarantee).
>
> E.g., you can assert that a list is sorted after running heapsort
> on it, but you need to enforce that a file is in the correct
> format.

I'd put it more strongly than that. assert is for program invariants. If the
condition is true, your program is outright broken. For performance reasons,
assertions are removed in release builds, but many folks think that they
should be left in and kill our program if they fail in release (and would be
why some folks won't compile with -release even in production). assert(0)
_does_ stay in your program in release mode and could be used in conjuction
with an if statement (since it doesn't have a condition to test), but it's
intended for unreachable code. Normally, assert throws an AssertError on
failure (assert(0) becomes an HLT instruction in release), and types derived
from Error are intended to kill your program on failure, precisely because
they indicate a bug in your program and if they fail, it means that your
program is in an undefined state (RangeError, which is use a failed bounds
check for an array would be another example of an Error).

Exceptions - specifically Exception or any type derived from it - are for
general error conditions that occur while a program is running but do not
necessarily indicate a bug in the program. Bad user input, stuff on disk,
anything in the environment, etc. - i.e. anything over which you have no
control -  generally would be the sort of thing that triggers an exception
when the program hits them. Exceptions are part of the normal operation of
your program and are expected to be recoverable (though a typical program
that hits no bad input would typically never need to throw an exception).

In general, the distinction between assertions and exceptions should be very
clear: assertions are for program invariants and exceptions are for when
your program encounters bad input or any other error condition that does not
indicate a bug in your program. Unfortunately however, the fact that enforce
looks the same as assert does seem to confuse some folks.

The only place that gets a bit debatable is testing arguments to a function,
and that really depends on the function's contract. If the function requires
that its input meet some conditions, and it's a bug if the caller does not
meet them, then an assertion should be used, whereas if it's not a bug in
the program if the caller provides bad input, then an exception is
appropriate. And when it should be considered a program bug and when it
should just be considered normal program execution depends on exactly what
the function is doing as well as your programming style (e.g. some folks
prefer that the caller be required to verify the correct input, whereas
others prefer that the callee do that; there are pros and cons to both). So,
that can get subjective. But ultimately, assertions are still for program
bugs, whereas exceptions are for normal error conditions that do not
indicate a bug in the program.

- Jonathan M Davis




More information about the Digitalmars-d-learn mailing list