Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

noscope and out!param

Version
Created
Status
Last modified
Author

created: 2015-01-18

last-modified: –

author: Zach Tollen

               Related:
               
               -   [DIP25: 'return' parameter attribute](http://wiki.dlang.org/DIP25)

Motive

The compiler must be able to know from a function’s signature how its reference parameters may escape. Armed with this information, the compiler can guarantee memory safety, and other things. Therefore, information about what a function does with its reference parameters must be transferred to its signature.

Any unsafe escape which is not marked in the signature should cause an error in @safe code, at least. Inference should be used eventually to alleviate the burden of manually marking the signatures.

In a Nutshell

There are three ways for a reference parameter to unsafely escape a function: by return, by global, and by mutable parameter. DIP25 introduces ‘return’ parameters in order to deal with escape by return. The current DIP introduces ‘noscope’ and ‘out!param’ to address the latter two, respectively.

Here are examples of the three ways:

static T* s;

T* fun(T* p1, T** p2) {
  // escape by global
  s = p1;
    
  // escape by return
  return p1;

  // escape by mutable argument
  *p2 = p1;
}

‘noscope’ simply means that the parameter’s reference may get copied to global pointers, as illustrated in ‘escape by global’ above.

‘out!param’, or ‘out!(param1, param2, …)’ means that any of the listed parameters’ references may get copied to where the attributed parameter points. ‘out!param’ is a completely different attribute from ‘out’. You would have to write both if necessary.

The above function, written with the new attributes:

T* fun(return noscope T* p1, out!p1 T** p2) {
  s = p1;    // escape by global: okay
  return p1; // escape by return: okay
  *p2 = p1;  // escape by mutable argument: okay
}

A more comprehensive description of how the compiler keeps track of its references is beyond the scope of this DIP.