Difference between revisions of "DIP71"

From D Wiki
Jump to: navigation, search
m (In a Nutshell)
 
(4 intermediate revisions by one other user not shown)
Line 19: Line 19:
 
|Links:
 
|Links:
 
|
 
|
Forum Discussion: http://forum.dlang.org /thread/xjhvpmjrlwhhgeqyoipv@forum.dlang.org
+
[http://forum.dlang.org/post/xjhvpmjrlwhhgeqyoipv@forum.dlang.org Forum Discussion]
 
Related:
 
Related:
 
* [http://wiki.dlang.org/DIP25 DIP25: 'return' parameter attribute]
 
* [http://wiki.dlang.org/DIP25 DIP25: 'return' parameter attribute]
 
|}
 
|}
  
== Abstract ==
+
== 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.
 
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.
Line 34: Line 34:
 
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.
 
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 the three ways: <syntaxhighlight lang=D>
+
Here are examples of the three ways: <syntaxhighlight lang=D>
 
static T* s;
 
static T* s;
  
Line 56: Line 56:
 
<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; // escape by global: okay
+
   s = p1;   // escape by global: okay
 
   return p1; // escape by return: okay
 
   return p1; // escape by return: okay
   *p2 = p1; // escape by mutable argument: okay
+
   *p2 = p1; // escape by mutable argument: 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.
 +
 +
 +
[[Category: DIP]]

Latest revision as of 19:53, 1 September 2015

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

Title: noscope and out!param
DIP: 71
Created: 2015-01-18
Last Modified: 2015-09-1
Author: Zach Tollen
Links:

Related:

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.