Difference between revisions of "DIP71"

From D Wiki
Jump to: navigation, search
m (In a Nutshell)
(In a Nutshell)
Line 60: Line 60:
 
<syntaxhighlight lang=D>
 
<syntaxhighlight lang=D>
 
T* fun(return noscope T* p1, out!p1 T** p2) {
 
T* fun(return noscope T* p1, out!p1 T** p2) {
   s = p1; //okay
+
   s = p1; // escape by global: okay
   
+
   return p1; // escape by return: okay
   return p1; //okay
+
   *p2 = p1; // escape by mutable argument: okay
 
 
   *p2 = p1; //okay
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
A more comprehensive description of how the compiler keeps track of its references is beyond the scope of this DIP.
 
A more comprehensive description of how the compiler keeps track of its references is beyond the scope of this DIP.

Revision as of 18:05, 18 January 2015

DIP71: 'noscope' and 'out!param' parameter attributes

Title: noscope
DIP: 71
Created: 2015-01-18
Last Modified: 2015-01-18
Author: Zach Tollen
Links:
  • Forum discussion:

Related:

Abstract

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. This DIP introduces 'noscope' and 'out!param' to address the latter two, respectively.

Here are 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;
}

DIP25 introduces 'return' parameters in order to deal with escape by return.

The current DIP introduces the parameter attributes 'noscope' and 'out!param' to deal with the others.

'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.