www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Feature request: empty behavior on assert failure

reply Dukc <ajieskola gmail.com> writes:
I think we're lacking a good option for assert failure behaviour 
for released code. Basically, we have two options.

One, crashing on assert failure. This may be a performance 
problem. It is customary for D code to assume the assertions will 
be removed on released code, and thus they are often used with 
little regard for performance.

Two, undefined behaviour. Of course, if an assert has gone boom 
it's not good news no matter what we do. The problem with 
undefined behaviour is that it defeats the purpose of leaving 
bounds checks in released code:
```D
 safe pure int fun(int[] arg)
{ import std.algorithm, std.range;
   assert(arg.length >= 10);
   // Cannot go out of bounds without violating the assertion 
above.
   // Array bounds check may be skipped.
   return arg.takeExactly(10).sum;
}
```

IMO we need an option for the compiler to delete the assertions, 
without being allowed to assume the assertion holds. The compiler 
would still be free to crash on assertion failure, if it deems 
that better for performance, but it could not trigger undefined 
behaviour. In other words, the compiler would treat `assert(x)` 
the same as:
```D
if(!x)
{ int v = void;
   if(v > 0) assert(false);
}
```

I also think this option should be the default, unless 
`-boundscheck=off`.
May 11 2022
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
In case you don't about this flag:

  -checkaction=[D|C|halt|context]
                     behavior on assert/boundscheck/finalswitch failure

Behavior on assert/boundscheck/finalswitch failure:
   =[h|help|?]    List information on all available choices
   =D             Usual D behavior of throwing an AssertError
   =C             Call the C runtime library assert failure function
   =halt          Halt the program execution (very lightweight)
   =context       Use D assert with context information (when available)
May 11 2022
parent Dukc <ajieskola gmail.com> writes:
On Wednesday, 11 May 2022 at 09:31:42 UTC, rikki cattermole wrote:
 In case you don't about this flag:

  -checkaction=[D|C|halt|context]
                     behavior on assert/boundscheck/finalswitch 
 failure

 Behavior on assert/boundscheck/finalswitch failure:
   =[h|help|?]    List information on all available choices
   =D             Usual D behavior of throwing an AssertError
   =C             Call the C runtime library assert failure 
 function
   =halt          Halt the program execution (very lightweight)
   =context       Use D assert with context information (when 
 available)
I do. It lets one to choose between different ways to crash the program on assertion failure. It does not let to continue with defined behaviour.
May 11 2022
prev sibling parent reply max haughton <maxhaton gmail.com> writes:
On Wednesday, 11 May 2022 at 09:26:43 UTC, Dukc wrote:
 I think we're lacking a good option for assert failure 
 behaviour for released code. Basically, we have two options.

 One, crashing on assert failure. This may be a performance 
 problem. It is customary for D code to assume the assertions 
 will be removed on released code, and thus they are often used 
 with little regard for performance.

 Two, undefined behaviour. Of course, if an assert has gone boom 
 it's not good news no matter what we do. The problem with 
 undefined behaviour is that it defeats the purpose of leaving 
 bounds checks in released code:
 ```D
  safe pure int fun(int[] arg)
 { import std.algorithm, std.range;
   assert(arg.length >= 10);
   // Cannot go out of bounds without violating the assertion 
 above.
   // Array bounds check may be skipped.
   return arg.takeExactly(10).sum;
 }
 ```

 IMO we need an option for the compiler to delete the 
 assertions, without being allowed to assume the assertion 
 holds. The compiler would still be free to crash on assertion 
 failure, if it deems that better for performance, but it could 
 not trigger undefined behaviour. In other words, the compiler 
 would treat `assert(x)` the same as:
 ```D
 if(!x)
 { int v = void;
   if(v > 0) assert(false);
 }
 ```

 I also think this option should be the default, unless 
 `-boundscheck=off`.
https://d.godbolt.org/z/ax4v5v9j3 If the assertions are turned off via `release` the assertions are completely gone, the optimizer doesn't know about them. I'd also like to note that anthropomorphizing compilers can be foolish, the "compiler" doesn't consciously do any undefined behaviour wrangling with D as per se because the backend/s don't really know anything about D.
May 11 2022
parent reply Dukc <ajieskola gmail.com> writes:
On Wednesday, 11 May 2022 at 09:47:32 UTC, max haughton wrote:
 If the assertions are turned off via `release` the assertions 
 are completely gone, the optimizer doesn't know about them.
Great! Only a spec change needed then.
 I'd also like to note that anthropomorphizing compilers can be 
 foolish,
What's anthropomorphising?
the "compiler" doesn't consciously do any undefined
 behaviour wrangling with D as per se because the backend/s 
 don't really know anything about D.
With the present spec there's no guarantee this will remain the case though: https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic .
May 11 2022
parent Tejas <notrealemail gmail.com> writes:
On Wednesday, 11 May 2022 at 10:12:16 UTC, Dukc wrote:
 On Wednesday, 11 May 2022 at 09:47:32 UTC, max haughton wrote:
 If the assertions are turned off via `release` the assertions 
 are completely gone, the optimizer doesn't know about them.
Great! Only a spec change needed then.
 I'd also like to note that anthropomorphizing compilers can be 
 foolish,
What's anthropomorphising?
the "compiler" doesn't consciously do any undefined
 behaviour wrangling with D as per se because the backend/s 
 don't really know anything about D.
With the present spec there's no guarantee this will remain the case though: https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic .
source : https://en.wikipedia.org/wiki/Anthropomorphism
 Anthropomorphism is the attribution of human traits, emotions, 
 or intentions to non-human entities.
May 11 2022