GC pragma on ref type: does disabling GC propagate to referenced objects?
0 reputation · 08 Dec 2021, 19:47 UTC
0 reputation · 08 Dec 2021, 19:47 UTC
When the gc pragma is applied to a ref type in Nim, the compiler requests that instances of that type are not tracked by the garbage collector. The language reference does not clarify whether this setting should also prevent the collector from tracing the objects that the reference points to. This ambiguity matters because a ref marked {.gc:"none".} may still point to a regular object that the runtime continues to scan, potentially retaining memory that the programmer expects to be untracked.
The behavior may vary between the Boehm and ARC garbage‑collection backends and between Nim 1.x and Nim 2.x, and the pragma is considered experimental. Consequently, developers must decide whether to rely on the pragma alone or to add explicit GC‑disabling annotations to the pointee type.
gc:none pragma on a ref type cause the runtime to omit tracing of the referenced object?{.gc:"none".} to achieve complete GC suppression?The short answer: no. Applying {.gc: "none".} to a ref type suppresses GC tracking of the reference itself — the pointer — not of the object it points to. The pragma does not propagate. If you want the pointee to be untracked as well, you must annotate the pointee type explicitly. The details below explain why, and where the behavior diverges between backends.
The gc pragma is attached to a type, and in Nim a ref T and its pointee T are distinct types. Marking the ref type tells the compiler to treat that reference more like a raw pointer: it is excluded from the collector's root/scanning bookkeeping for that type. The pointee's own type definition still governs whether the collector traces it. So a ref object marked {.gc: "none".} pointing at an ordinary object leaves that object fully scannable — exactly the retention surprise described in the question.
The mechanism differs by memory-management backend, and this is where version assumptions matter:
Because the pragma is experimental and the default backend changed between Nim 1.x and 2.x, treat any cross-version claim as provisional and verify on your exact compiler version.
{.gc: "none".} if you want complete suppression; annotating only the ref is insufficient.Since behavior here is version- and backend-sensitive, confirm empirically rather than trusting documentation:
# Compile with each backend and inspect generated C for GC registration calls
nim c --gc:boehm -d:danger yourtest.nim
nim c --mm:arc -d:danger yourtest.nim
Compare the generated C for a plain ref versus the annotated ref: the absence of GC registration/scanning calls for the annotated type confirms the pointer-level suppression. A small allocation loop plus a forced collection can then show whether the pointee is still traced. If your decision hinges on exact Nim 2.x semantics, include your compiler version (nim --version) when seeking confirmation — that single detail determines which answer applies.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.