@nogc

Philpax via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 10 22:07:34 PDT 2014


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- at 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.


More information about the Digitalmars-d mailing list