Specifying @nogc on structs seems to have no effect

Craig Black craigblack1234 at gmail.com
Tue Sep 19 18:06:32 UTC 2017


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


More information about the Digitalmars-d mailing list