I've run into my own series of trials and tribulations with a @nogc main function (i.e. entire project is @nogc). While the idea and implementation is great, its interaction with druntime/Phobos is lacking. This isn't a complete list - it's only what I remember and can reproduce now:

1. destroy(Object) seems to not call the dtor; I'm not sure this is an issue with 2.066 or nogc, seeing as it happens in 2.065 as well: http://dpaste.dzfl.pl/d0c754bb78c6 - to get around this, I wrote my own destroy that automatically calls __dtor.

2. std.typecons.RefCounted doesn't compile in @nogc as the dtor isn't @nogc. Attempted to annotate it with @nogc, but then this happened: Error: @nogc function 'std.typecons.RefCounted!(Test, cast(RefCountedAutoInitialize)1).RefCounted.~this' cannot call non-@nogc function 'object.destroy!(Test).destroy'. Also attempts to call GC.removeRange, which fails for obvious reasons. Got around this by writing my own ref-counted pointer that uses the destroy replacement from (1).

3. std.container.Array doesn't compile in @nogc as it uses std.typecons.RefCounted. Got around this by writing my own Array type.

4. @nogc code takes on some of the characteristics of nothrow as Phobos/druntime liberally use `throw new Exception` and `enforce`. This leads to a _vast_ majority of the standard library being locked out. This is really one of the killer issues, and it can only be resolved with allowing GC allocations in failure situations (as Walter says) or by pre-allocating exceptions in the stdlib (which is unlikely). Out of curiosity, as I haven't looked at this problem, what does D do differently to C++ that requires heap allocation of exceptions?

5. As a result of (4), even some of the most trivial things don't work. std.stdio.writeln() (i.e. no arguments) fails because of this:
enforce(fputc('\n', .stdout._p.handle) == '\n');
There is _no need_ to enforce that \n was actually output! This is absolutely ridiculous! I got around this by writing my own wrapper around printf that doesn't allocate or throw.

6. std.allocator doesn't work with @nogc. Understandable, since it hasn't been updated for @nogc yet. Got around this by starting work on my own allocators.

7. This is more a tangential issue, but still a mild irritant: placing @nogc at a top of a file doesn't cover the entire module - structs and classes also have to be manually tagged @nogc:
module test;
@nogc:
struct Test
{
    @nogc:
    this() { /* ... */ }
}

I ran into these issues with GIT HEAD from 2-3 weeks ago. When I resume work on my @nogc project, I'll update to the 2.066 beta/release and report on any more issues. I'm aware that it's early days yet for @nogc, so I'm not fussed about these issues, but they are rather concerning. I considered sending in PRs to resolve some of these problems, but fixing the Exception situation (which many of the above stem from) requires significant work.

Reply via email to