On 9/19/17 10:22 AM, Craig Black wrote:
On Tuesday, 19 September 2017 at 13:59:27 UTC, Jonathan M Davis wrote:
On Tuesday, September 19, 2017 13:11:03 Craig Black via Digitalmars-d
wrote:
I've recently tried coding in D again after some years. One of my
earlier concerns was the ability to code without the GC, which seemed
difficult to pull off. To be clear, I want my programs to be garbage
collected, but I want to use the GC sparingly so that the mark and
sweep collections will be fast.
So I want guarantees that certain sections of code and certain
structs will not require the GC in any way.
I realize that you can allocate on the non-GC heap using malloc and
free and emplace, but I find it troubling that you still need to tell
the GC to scan your allocation. What I would like is, for example, to
be able to write a @nogc templated struct that guarantees that none
of its members require GC scanning. Thus:
@nogc struct Array(T)
{
...
}
class GarbageCollectedClass
{
}
void main()
{
Array!int intArray; // fine
}
@nogc is a function attribute. It has no effect on types except on
their member functions. All it does is guarantee that a function
marked with @nogc cannot call any function which is not @nogc and
cannot do any operation which is not considered @nogc. It's to
guarantee that a function does not use the GC and has nothing more to
do with types than attributes like @safe or nothrow do.
Thank you for your response. The @nogc attribute is good, but in my
opinion it is incomplete if all types still require scanning. The
purpose of not employing GC in certain sections of code is performance,
and we are sacrificing performance with every allocation unit that is
needlessly scanned.
From your posts and responses, it looks like you misunderstand still
what the @nogc attribute does.
Note that a type does not bear any relation to whether the memory it
lives in is scanned or not -- EXCEPT -- whether the type has
indirections (pointers or arrays). A type which contains indirections is
scanned, one that does not contain them is not scanned. There is no way
to mark a type such that it:
1. Cannot be allocated on the GC*
2. Would not be scanned if it has pointers.
You can manually allocate it elsewhere, and you can manually tell the GC
not to scan that block, but those are low-level tools that normally
aren't used except by experts.
The @nogc attribute is used to PREVENT any operation that could cause a
scan to occur. The idea is to mark areas of your code in such a way that
you can predict the execution expense of that code. That is, if you have
a tight loop or are in the middle of rendering frames to the screen in a
game or something, you want to have the compiler ensure no GC cycles
happen. It does not mean "don't ever store this in the GC."
-Steve
* There is a deprecated feature of D that allows specifying how to
allocate classes other than heap allocation, but I wouldn't recommend
using it. See: https://dlang.org/spec/class.html#allocators