Thread overview
Using enforce or assert to check for fullness when appending to fixed length array container
Oct 04, 2019
Per Nordlöw
Oct 04, 2019
Tobias Pankrath
Oct 04, 2019
Jonathan M Davis
October 04, 2019
I have a wrapper container FixedArray at

https://github.com/nordlow/phobos-next/blob/25f4a4ee7347427cebd5cd375c9990b44108d2ef/src/fixed_array.d

on top of a static array store that provides the member

    void insertBack(Es...)(Es es) @trusted
    if (Es.length <= capacity) // TODO use `isAssignable`
    {
        import std.exception : enforce;
        enforce(_length + Es.length <= capacity, `Arguments don't fit in array`); // TODO use assert insteead?

        foreach (immutable i, ref e; es)
        {
            moveEmplace(e, _store[_length + i]); // TODO remove `move` when compiler does it for us
        }
        _length = cast(Length)(_length + Es.length); // TODO better?
    }

Is the usage of `enforce` to check for out of bounds (fullness) idiomatic D or should an `assert()` be used instead?
October 04, 2019
On Friday, 4 October 2019 at 10:00:08 UTC, Per Nordlöw wrote:
> Is the usage of `enforce` to check for out of bounds (fullness) idiomatic D or should an `assert()` be used instead?

I'd say it should follow -boundscheck: https://dlang.org/dmd-linux.html#switch-boundscheck

Does that set an version identifier?
October 04, 2019
On Friday, October 4, 2019 4:00:08 AM MDT Per Nordlöw via Digitalmars-d- learn wrote:
> I have a wrapper container FixedArray at
>
> https://github.com/nordlow/phobos-next/blob/25f4a4ee7347427cebd5cd375c9990 b44108d2ef/src/fixed_array.d
>
> on top of a static array store that provides the member
>
>      void insertBack(Es...)(Es es) @trusted
>      if (Es.length <= capacity) // TODO use `isAssignable`
>      {
>          import std.exception : enforce;
>          enforce(_length + Es.length <= capacity, `Arguments don't
> fit in array`); // TODO use assert insteead?
>
>          foreach (immutable i, ref e; es)
>          {
>              moveEmplace(e, _store[_length + i]); // TODO remove
> `move` when compiler does it for us
>          }
>          _length = cast(Length)(_length + Es.length); // TODO
> better?
>      }
>
> Is the usage of `enforce` to check for out of bounds (fullness)
> idiomatic D or should an `assert()` be used instead?

It depends entirely on how you intend for it to be used. Is it a bug if anyone attempts to append when there's no space, or is that normal program behavior that should be handled and recovered from? Most typically, with D, it would be considered a bug, and the caller should be sure that there's room before attempting to append, but depending on your use case, using exceptions may be more appropriate. However, if you don't have a really good reason to treat it as a recoverable error condition rather than a bug, I'd suggest that you treat it as a bug.

Also, you could treat it as a RangeError instead of an AssertError (the main difference being that with assert, the checks go away when -release is used). However, if your code would trigger a RangeError when accessing the static array anyway, then you could just forgo all checks entirely and let druntime throw a RangeError.

- Jonathan M Davis