Difference between revisions of "DIP38"
Timotheecour (talk | contribs) (Created page with "== DIP34: Static array literals (STILL EDITING -- don't read yet) == {| class="wikitable" !Title: !'''Static array literals''' |- |DIP: |34 |- |Version: |1 |- |Status: |Dra...") |
Timotheecour (talk | contribs) |
||
Line 3: | Line 3: | ||
{| class="wikitable" | {| class="wikitable" | ||
!Title: | !Title: | ||
− | !'' | + | !''Safe references and rvalue references without runtime checks'' |
|- | |- | ||
|DIP: | |DIP: | ||
− | | | + | |38 |
|- | |- | ||
|Version: | |Version: | ||
Line 15: | Line 15: | ||
|- | |- | ||
|Created: | |Created: | ||
− | |2013- | + | |2013-05-06 |
|- | |- | ||
|Last Modified: | |Last Modified: | ||
− | |2013- | + | |2013-05-06 |
|- | |- | ||
|Author: | |Author: |
Revision as of 18:28, 6 May 2013
Contents
DIP34: Static array literals (STILL EDITING -- don't read yet)
Title: | Safe references and rvalue references without runtime checks |
---|---|
DIP: | 38 |
Version: | 1 |
Status: | Draft |
Created: | 2013-05-06 |
Last Modified: | 2013-05-06 |
Author: | Timothee Cour |
Links: |
Abstract
Safe references and rvalue references without runtime checks.
auto x=[1,2,3]S;
static assert(is(typeof(x)==int[3]));
The particular choice of 'S' can be discussed.
Description
Dconf13 introduced safe references enabled by a runtime check (see email thread from Walter: 'Rvalue references - The resolution'). I propose a formulation that is safe, yet doesn't require any runtime check. The compiler automatically annotates any return by ref function with a dependency on input arguments:
eg:
struct U{T x;}
ref T foo(ref T a, ref T b, ref U c, T d){
if(condition)
return a;
else if(condition(b))
return c.x;
else
return d;
}
will be rewritten internally by the compiler as having the signature:
ref(0,2) T foo(ref T a, ref T b, ref T c, T d);
indicating that ref depends on ref arguments 0(a) and 2 (c) (dependency on c is via field access). The other arguments are not in the list because they're not input ref arguments, or not returned.
Second example: when the function is a member (say of a struct), the 'this' parameter is implicitly argument number 0, but the same rules apply:
struct S { T t; ref T fooc(ref T a) { if(condition) return t; else return a;} }
will be rewritten internally by the compiler as having the signature:
struct S { T t; ref(0,1) T fooc(ref T a); }
because there's a ref dependency on 0(this) and 1(a).
Note, if there's no dependency on input ref arguments (for example, it returns by ref a global), then the ref list is empty, ie ref().
Given those compiler generated annotations, it is easy to validate/invalidate ref safety: the rule is: in any return statement of a ref-return function, the ref dependency list can only refer to: A) global variables (gc-alloced, static etc) B) ref inputs This excludes locals.
Examples: taken from Walter's above mentioned email:
//Case A:
ref T fooa(ref T t) { return t; }
//=> ref(0) T fooa(ref T t);
ref T bar() { T t; return fooa(t); } // error since 0 refers to t which is a local
//Case B:
ref T foob(ref U u) { return u.t; }
//=>ref(0) T foob(ref U u) { return u.t; }
ref U bar() { T t; return foob(t); } // error since 0 refers to t which is a local
//Case C:
struct S { T t; ref T fooc() { return t; } }
//=>struct S { T t; ref(0) T fooc(); } //0 refers to 'this'
ref T bar() { S s; return s.fooc(); } // error since 0 refers to this = s, which is local
//Case D:
Returning ref to uplevel local:
ref T food() {
T t;
ref T bar() { return t; }
//=>ref(0) T bar(); // 0 here indicates an implicit 'this' pointing to local stack allocated variables (wouldn't be the case if t were static variable)
return bar(); //error since 0 refers to local stack
}
//case E:
Transitively calling other functions:
ref T fooe(T t) { return ref fooa(t); } //error since we have the compiler rewrite 'ref(0) T fooa(ref T t);' and 0 refers to t, a local variable (t is not a ref variable in fooe).
Final point: the di files will have to write those annotations written down, which shall be done automatically.
Usage
To start a new DIP you can go to Edit link and copy the source of this DIP, then go to DIP index and add a new item in the list. The DIP number should be one more than the last DIP in the index (for example, if the DIP1 is the last DIP, your DIP should be DIP2). The link in the index should have the form: [[DIPx]], Title, Status, resume. Where x is the DIP number, title is the DIP title and resume is a short description about the DIP.
Save the DIP index page and click on the new red link. Now you are editing the new DIP you just created, now paste the copied source text from this template and replace all the you need.
Remember to update the metadata at the start of the DIP, and keep it as a Draft at the beginning. When your DIP is done, you should announce it in the News Group for discussion, with a subject like this: new DIPx: title (where one more time x is the DIP number and title is the DIP title).
You should always put you DIPs in the Public Domain (or a similarly permissive license but use Public Domain unless you're very sure of what you're doing).
Recommendations
When writing a DIP, try not to express your opinion. DIPs should provide facts and be as objective as possible. Even when that's pretty hard, you can make the DIP look more objective by not using, for example, "I prefer XXX because YYY". If YYY is an objective advantage, write that in a more objective way, like "XXX can be a better option because YYY". Try to leave non-technical personal preferences aside; "XXX can be a better option because the syntax is nicer" is not good enough even when you don't say "I prefer".
Try not to include half-baked ideas. If you are not sure about something, leave it outside the DIP and write it on the NG announcement instead for further discussion. The idea can be added to the DIP in the future when it is in a better shape.
Abstract
Make the abstract as descriptive as possible (while keeping it brief). From an abstract you should be able to tell what the DIP is about, you should introduce for every non-trivial concept a person should know for understanding the DIP (or provide links if you can't briefly describe those concepts in the abstract). Don't copy the title of the DIP to use it as an abstract. Ideally an abstract should be a paragraph 5 to 10 lines long.
Rationale
Rationale should be complete. When the DIP tries to solve a problem, try to describe that problem as detailed as possible. If you have links to the NG describing the problem more deeply, used them. All the background information is welcome.
NG Announcement
When posting the DIP announcement to the NG, please copy the abstract, so people can easily know what is it about and follow the link if they are interested.
Copyright
This document has been placed in the Public Domain.