Bug 24331 – @nogc and GC.disable() are often confused
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P1
Component
dlang.org
Product
D
Version
D2
Platform
All
OS
All
Creation time
2024-01-11T22:26:45Z
Last change time
2024-01-12T04:24:21Z
Keywords
industry, pull
Assigned to
No Owner
Creator
Walter Bright
Comments
Comment #0 by bugzilla — 2024-01-11T22:26:45Z
Adam Wilson writes:
@nogc works just fine. We recently spent a good chunk of time in Discord educating a newbie on what it actually does.
What @nogc is specified to do: Prevent GC allocations from occurring. Fantastic. What people actually do with @nogc: Use it to selectively disable the GC without using GC.disable().
The reason for this stems from a side-effect of how the current GC operates. Because allocations are the trigger for collections, by preventing allocations, collections are also prevented. And what people really want to do is disable collections because they don't like the collection pauses. They don't actually care about the allocations per se because that is generally as fast as a malloc and they are going to have to allocate at some point anyways.
So @nogc works exactly as specified, but because of an unspecified implementation side-effect, that is not guaranteed to hold true in the future, the @nogc crowd writes their code as if @nogc does something else entirely. And we end up here in this thread.
Comment #1 by bugzilla — 2024-01-11T22:27:44Z
Sounds like better documentation is needed for both @nogc and GC.disable().
Comment #2 by timon.gehr — 2024-01-11T22:42:37Z
(In reply to Walter Bright from comment #1)
> Sounds like better documentation is needed for both @nogc and GC.disable().
Well, currently, the spec states:
How Garbage Collection Works
-----------------------------
The GC works by:
- Stopping all other threads than the thread currently trying to allocate GC memory.
- ‘Hijacking’ the current thread for GC work.
- Scanning all ‘root’ memory ranges for pointers into GC allocated memory.
- Recursively scanning all allocated memory pointed to by roots looking for more pointers into GC allocated memory.
- Freeing all GC allocated memory that has no active pointers to it and do not need destructors to run.
- Queueing all unreachable memory that needs destructors to run.
- Resuming all other threads.
- Running destructors for all queued memory.
- Freeing any remaining unreachable memory.
- Returning the current thread to whatever work it was doing.
https://dlang.org/spec/garbage.html
So what people are relying on is currently indeed specified behavior. This can of course be changed, but I do not think we can fault users for relying on this documented behavior of the GC.
Comment #3 by dlang-bot — 2024-01-12T03:14:31Z
@WalterBright created dlang/dlang.org pull request #3756 "fix Issue 24331 - @nogc and GC.disable() are often confused" fixing this issue:
- fix Issue 24331 - @nogc and GC.disable() are often confused
https://github.com/dlang/dlang.org/pull/3756
Comment #4 by dlang-bot — 2024-01-12T03:29:10Z
@WalterBright created dlang/dmd pull request #16023 "fix Issue 24331 - @nogc and GC.disable() are often confused" fixing this issue:
- fix Issue 24331 - @nogc and GC.disable() are often confused
https://github.com/dlang/dmd/pull/16023
Comment #5 by dlang-bot — 2024-01-12T03:51:13Z
dlang/dlang.org pull request #3756 "fix Issue 24331 - @nogc and GC.disable() are often confused" was merged into master:
- 5c56620fa0fbfc2db75e681751abbd5f85758cb1 by Walter Bright:
fix Issue 24331 - @nogc and GC.disable() are often confused
https://github.com/dlang/dlang.org/pull/3756
Comment #6 by dlang-bot — 2024-01-12T04:24:21Z
dlang/dmd pull request #16023 "fix Issue 24331 - @nogc and GC.disable() are often confused" was merged into master:
- e04af29b775a42417d43081fdc905021766b6bb4 by Walter Bright:
fix Issue 24331 - @nogc and GC.disable() are often confused
https://github.com/dlang/dmd/pull/16023