www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - cost of safe and safety inference

reply "monarch_dodra" <monarchdodra gmail.com> writes:
I was on vacation last week, mostly without internet and even 
less D, which gave me the time to have existential thoughts 
(about D ^^).

The issue I'm thinking about is  safe.  safe has a double 
function:
1) Restrict any any usage of "unsafe" code.
2) Bounds check slices, even in release mode.

I think that when you ask for safe code, then 1) is always 
desired. 2), on the other hand, and not always desired. In 
particular, the only way to turn off 2) is with the global 
"-noboundscheck" hook.

...

Things get fun with D's attribute inference. As you know, D is 
able to infer if a function is nothrow... or safe!

So here's the kicker: You wrote a template that is potentially 
safe. The D compiler tags it as safe. Awesome. BUT, because it's 
safe, it also means it is bounds checked, even in release. Not 
only is this (probably) not desired, but it is also *very* 
not-obvious.

Take this "dumb" program:

//----
int[] a;

int foo()()
{
     return a[4];
}
void main()
{
   a = [1, 2, 3];
   foo!()();
}
//----

You know what you get in release? A range error because foo!() is 
safe, and the compiler generated the associated bounds checking. 
To override this, foo must be explicitly tagged as  system.

FACT: I have NEVER seen ANYBODY use  system, be it in phobos, or 
user code.

This is counter intuitive, because for normal functions,  safe is 
"opt-in". For templates though, when possible, safety becomes 
opt-*out*. Weird 0_o.

Has anybody else though about these kinds of issues before? I'm 
wondering how many of our algorithm benchmarks this has 
clobbered, and in which ratio this could be a factor of D's "bad" 
performance relative to C++?.


----------------------------------------------------------
----------------------------------------------------------


Solution?

This may be crazy, but given that "safe" is not free, I think 
"default" safety inference should be dropped.

However, templates would have an opt-in "safe if possible" 
keyword " optsafe":

A template marked " optsafe" would ban any unsafe code that does 
not depend on parametrization. It would always check bounds of 
arrays (provided no -noboundscheck).

However, if at the end of the day, there is unsafe parametrized 
usage, then the final template just won't be marked as  safe.

Thoughts?
Mar 11 2013
next sibling parent "deadalnix" <deadalnix gmail.com> writes:
If anything, safety must be opt-out. I conclude the exact 
opposite : function must be  safe by default or inferred as 
templates.
Mar 11 2013
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 11 March 2013 at 15:20:05 UTC, deadalnix wrote:
 If anything, safety must be opt-out. I conclude the exact 
 opposite : function must be  safe by default or inferred as 
 templates.

That would have been nice too, but too crippling as is. If and when we have all those sweet non-escapable references and whatnot, then maybe we could set it as optout by default via compiler switch? Having "blocks tag-able with attributes" would help too. I wish more people would push for that. It would be an awesome feature, which I dare say would be as useful as the scope block.
Mar 11 2013
prev sibling parent kenji hara <k.hara.pg gmail.com> writes:
--089e013c6c0e39d54704d7a8aea0
Content-Type: text/plain; charset=UTF-8

If you want to opt-out safety from template function foo, you can just add
 system attribute to it.

int[] a;
 system int foo()() { return a[0]; }
void main() { foo!()(); }

$ dmd -run test
core.exception.RangeError test(3): Range violation

$ dmd -release -run test
object.Error: Access Violation

Kenji Hara


2013/3/11 monarch_dodra <monarchdodra gmail.com>

 I was on vacation last week, mostly without internet and even less D,
 which gave me the time to have existential thoughts (about D ^^).

 The issue I'm thinking about is  safe.  safe has a double function:
 1) Restrict any any usage of "unsafe" code.
 2) Bounds check slices, even in release mode.

 I think that when you ask for safe code, then 1) is always desired. 2), on
 the other hand, and not always desired. In particular, the only way to turn
 off 2) is with the global "-noboundscheck" hook.

 ...

 Things get fun with D's attribute inference. As you know, D is able to
 infer if a function is nothrow... or safe!

 So here's the kicker: You wrote a template that is potentially safe. The D
 compiler tags it as safe. Awesome. BUT, because it's safe, it also means it
 is bounds checked, even in release. Not only is this (probably) not
 desired, but it is also *very* not-obvious.

 Take this "dumb" program:

 //----
 int[] a;

 int foo()()
 {
     return a[4];
 }
 void main()
 {
   a = [1, 2, 3];
   foo!()();
 }
 //----

 You know what you get in release? A range error because foo!() is safe,
 and the compiler generated the associated bounds checking. To override
 this, foo must be explicitly tagged as  system.

 FACT: I have NEVER seen ANYBODY use  system, be it in phobos, or user code.

 This is counter intuitive, because for normal functions,  safe is
 "opt-in". For templates though, when possible, safety becomes opt-*out*.
 Weird 0_o.

 Has anybody else though about these kinds of issues before? I'm wondering
 how many of our algorithm benchmarks this has clobbered, and in which ratio
 this could be a factor of D's "bad" performance relative to C++?.


 ------------------------------**----------------------------
 ------------------------------**----------------------------


 Solution?

 This may be crazy, but given that "safe" is not free, I think "default"
 safety inference should be dropped.

 However, templates would have an opt-in "safe if possible" keyword
 " optsafe":

 A template marked " optsafe" would ban any unsafe code that does not
 depend on parametrization. It would always check bounds of arrays (provided
 no -noboundscheck).

 However, if at the end of the day, there is unsafe parametrized usage,
 then the final template just won't be marked as  safe.

 Thoughts?

--089e013c6c0e39d54704d7a8aea0 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">If you want to opt-out safety from template function foo, = you can just add system attribute to it.<div><br></div><div>int[] a;</div>= <div> system int foo()() { return a[0]; }</div><div>void main() { foo!()();= }</div> <div style><br></div><div style><div>$=C2=A0dmd -run test</div><div>core.ex= ception.RangeError test(3): Range violation<br></div></div><div style><br><= /div><div style><div>$ dmd -release -run test</div><div>object.Error: Acces= s Violation<br> </div></div><div style><br></div><div style>Kenji Hara</div></div><div clas= s=3D"gmail_extra"><br><br><div class=3D"gmail_quote">2013/3/11 monarch_dodr= a <span dir=3D"ltr">&lt;<a href=3D"mailto:monarchdodra gmail.com" target=3D= "_blank">monarchdodra gmail.com</a>&gt;</span><br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex">I was on vacation last week, mostly without = internet and even less D, which gave me the time to have existential though= ts (about D ^^).<br> <br> The issue I&#39;m thinking about is safe. safe has a double function:<br> 1) Restrict any any usage of &quot;unsafe&quot; code.<br> 2) Bounds check slices, even in release mode.<br> <br> I think that when you ask for safe code, then 1) is always desired. 2), on = the other hand, and not always desired. In particular, the only way to turn= off 2) is with the global &quot;-noboundscheck&quot; hook.<br> <br> ...<br> <br> Things get fun with D&#39;s attribute inference. As you know, D is able to = infer if a function is nothrow... or safe!<br> <br> So here&#39;s the kicker: You wrote a template that is potentially safe. Th= e D compiler tags it as safe. Awesome. BUT, because it&#39;s safe, it also = means it is bounds checked, even in release. Not only is this (probably) no= t desired, but it is also *very* not-obvious.<br> <br> Take this &quot;dumb&quot; program:<br> <br> //----<br> int[] a;<br> <br> int foo()()<br> {<br> =C2=A0 =C2=A0 return a[4];<br> }<br> void main()<br> {<br> =C2=A0 a =3D [1, 2, 3];<br> =C2=A0 foo!()();<br> }<br> //----<br> <br> You know what you get in release? A range error because foo!() is safe, and= the compiler generated the associated bounds checking. To override this, f= oo must be explicitly tagged as system.<br> <br> FACT: I have NEVER seen ANYBODY use system, be it in phobos, or user code.= <br> <br> This is counter intuitive, because for normal functions, safe is &quot;opt= -in&quot;. For templates though, when possible, safety becomes opt-*out*. W= eird 0_o.<br> <br> Has anybody else though about these kinds of issues before? I&#39;m wonderi= ng how many of our algorithm benchmarks this has clobbered, and in which ra= tio this could be a factor of D&#39;s &quot;bad&quot; performance relative = to C++?.<br> <br> <br> ------------------------------<u></u>----------------------------<br> ------------------------------<u></u>----------------------------<br> <br> <br> Solution?<br> <br> This may be crazy, but given that &quot;safe&quot; is not free, I think &qu= ot;default&quot; safety inference should be dropped.<br> <br> However, templates would have an opt-in &quot;safe if possible&quot; keywor= d &quot; optsafe&quot;:<br> <br> A template marked &quot; optsafe&quot; would ban any unsafe code that does = not depend on parametrization. It would always check bounds of arrays (prov= ided no -noboundscheck).<br> <br> However, if at the end of the day, there is unsafe parametrized usage, then= the final template just won&#39;t be marked as safe.<br> <br> Thoughts?<br> </blockquote></div><br></div> --089e013c6c0e39d54704d7a8aea0--
Mar 11 2013