On Tuesday, 19 September 2017 at 15:15:05 UTC, Steven
Schveighoffer wrote:
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
Thank you for the clarification. I understand mow that @nogc is
only for functions and not for data types. Thinking out loud, it
would seem beneficial if there was a way to mark a pointer or
data structure as not pointing to the GC heap. A guarantee to the
compiler and run-time to ignore it during GC sweeps. Now I know
that pointer arithmetic breaks every kind of guarantee that would
have with pointers, but aside from that it would seem to me that
the compiler could help to enforce data marked as non-GC to not
be assigned GC heap allocations. This wouldn't be allowed for
classes or class references, since they are always pointing to GC
data, but perhaps for pointers and structs. It seems like it
would be a helpful feature, but maybe I'm way off base.
-Craig