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.