Specifying @nogc on structs seems to have no effect

Steven Schveighoffer schveiguy at yahoo.com
Tue Sep 19 15:15:05 UTC 2017

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


* 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

More information about the Digitalmars-d mailing list