diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2020-05-12 15:46:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-12 15:46:24 +0200 |
commit | 06dfd316127fb2ec05ff69942abd1e279156ac5c (patch) | |
tree | 4bb6a8ac4ea04ed2ff5bb34c1fe9ff47b43c2ce1 /doc/destructors.rst | |
parent | 4277ab470a20f429605fbf238e485ea24b01706a (diff) | |
download | Nim-06dfd316127fb2ec05ff69942abd1e279156ac5c.tar.gz |
fixes #13881
* fixes #13881 * documented changed requirements for system.onThreadDestruction * destructors.rst: update the documentation
Diffstat (limited to 'doc/destructors.rst')
-rw-r--r-- | doc/destructors.rst | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/doc/destructors.rst b/doc/destructors.rst index 2b1222778..e7ebd93ea 100644 --- a/doc/destructors.rst +++ b/doc/destructors.rst @@ -469,10 +469,51 @@ for expressions of type ``lent T`` or of type ``var T``. echo t[0] # accessor does not copy the element! +The .cursor annotation +====================== + +Under the ``--gc:arc|orc`` modes Nim's `ref` type is implemented via the same runtime +"hooks" and thus via reference counting. This means that cyclic structures cannot be freed +immediately (``--gc:orc`` ships with a cycle collector). With the ``.cursor`` annotation +one can break up cycles declaratively: + +.. code-block:: nim + + type + Node = ref object + left: Node # owning ref + right {.cursor.}: Node # non-owning ref + +But please notice that this is not C++'s weak_ptr, it means the right field is not +involved in the reference counting, it is a raw pointer without runtime checks. + +Automatic reference counting also has the disadvantage that it introduces overhead +when iterating over linked structures. The ``.cursor`` annotation can also be used +to avoid this overhead: + +.. code-block:: nim + + var it {.cursor.} = listRoot + while it != nil: + use(it) + it = it.next + + +In fact, ``.cursor`` more generally prevents object construction/destruction pairs +and so can also be useful in other contexts. The alternative solution would be to +use raw pointers (``ptr``) instead which is more cumbersome and also more dangerous +for Nim's evolution: Later on the compiler can try to prove ``.cursor`` annotations +to be safe, but for ``ptr`` the compiler has to remain silent about possible +problems. + Owned refs ========== +**Note**: The ``owned`` type constructor is only available with +the ``--newruntime`` compiler switch and is experimental. + + Let ``W`` be an ``owned ref`` type. Conceptually its hooks look like: .. code-block:: nim @@ -568,14 +609,14 @@ used to specialize the object traversal in order to avoid deep recursions: type Node = ref object x, y: int32 - left, right: owned Node + left, right: Node type Tree = object - root: owned Node + root: Node proc `=destroy`(t: var Tree) {.nodestroy.} = # use an explicit stack so that we do not get stack overflows: - var s: seq[owned Node] = @[t.root] + var s: seq[Node] = @[t.root] while s.len > 0: let x = s.pop if x.left != nil: s.add(x.left) |