trick to make throwing method @nogc

Guest via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Feb 26 18:06:16 PST 2017


On Saturday, 25 February 2017 at 19:59:29 UTC, ikod wrote:
> Hello,
>
> I have a method for range:
>
> struct Range {
>     immutable(ubyte[]) _buffer;
>     size_t             _pos;
>
>     @property void popFront() pure @safe {
>         enforce(_pos < _buffer.length, "popFront from empty 
> buffer");
>         _pos++;
>     }
> }
>
> I'd like to have @nogc here, but I can't because enforce() is 
> non- at nogc.
> I have a trick but not sure if it is valid, especially I don't 
> know if optimization will preserve code, used for throwing:
>
> import std.string;
>
> struct Range {
>     immutable(ubyte[]) _buffer;
>     size_t  _pos;
>
>     this(immutable(ubyte[]) s) {
>         _buffer = s;
>     }
>     @property void popFront() pure @safe @nogc {
>         if (_pos >= _buffer.length ) {
>             auto _ = _buffer[$]; // throws RangeError
>         }
>         _pos++;
>     }
> }
>
> void main() {
> 	auto r = Range("1".representation);
> 	r.popFront();
> 	r.popFront(); // throws
> }
>
> Is it ok to use it? Is there any better solution?
>
> Thanks!

solution 1/
===========

You can throw a static Exception.

auto staticEx(string msg, string file = __FILE__, size_t line = 
__LINE__)() @nogc
{
     immutable static Exception e = new Exception(msg, file, line);
     return e;
}

void main() @nogc
{
     throw staticEx!"bla";
}

not good for the call stack display, tho.

solution 2/
===========

Throw an Error. Errors shouldn't be caugth and consequently they 
lead to program termination so you don't care about the leak.


import std.experimental.allocator: make;
import std.experimental.allocator.mallocator: Mallocator;

void main() @nogc
{
     throw make!Error(Mallocator.instance, "bla");
}

good when errors are not designed to be caught. not good for 
exceptions because might leak to death depending on how the 
exceptions happens (i.e in a loop ouch).

solution 3/
===========

Reference counting. Not explored so far.

To finish, using a assert(0) is bad. assert(0) throws an error, 
it's really not like an Exception.


More information about the Digitalmars-d-learn mailing list