July 31, 2014
On 7/31/2014 12:01 AM, simendsjo wrote:
> On 07/31/2014 12:01 AM, Walter Bright wrote:
> (...)
>> 2. The compiler can make use of assert expressions to improve
>> optimization, even in -release mode.
> (...)
>
> Does this mean that assertions used for optimization will be left in
> -release? There's plenty of times where I've had an old incorrect
> assertion in my code after a refactoring - sometimes in seldom used paths.
>
> If the compiler would aggressively optimize my code based on some wrong
> assumptions I give it, it would be very useful if that assumption would
> stay in the code to trigger an assertion.

To get this behavior, don't use the -release switch.

July 31, 2014
On 7/30/2014 4:05 PM, Ary Borenszweig wrote:
> On 7/30/14, 7:01 PM, Walter Bright wrote:
>> I'd like to sum up my position and intent on all this.
>>
>> 7. using enforce() to check for program bugs is utterly wrong. enforce()
>> is a library creation, the core language does not recognize it.
>
> What do you suggest to use to check program bugs?

assert()
July 31, 2014
On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote:
> I'd like to sum up my position and intent on all this.
>
> 1. I can discern no useful, practical difference between the notions of assume and assert.

People have explained the difference repeatedly, a ridiculous number of times now. Could you please take a minute to understand it this time instead of flippantly dismissing it again?

assert does a runtime check, assume does not
assume affects code generation/optimization, assert does not
assert is for debugging, assume is not
assume is for optimization, assert is not

In terms of what they practically do, they have *nothing* in common, their functions are entirely orthogonal.

Still think there is no practical difference?

> 2. The compiler can make use of assert expressions to improve optimization, even in -release mode.

This will introduce a lot of undefined behavior, including making @safe code with asserts unsafe. I really think this needs to be acknowledged. As far as I can tell from the other thread, it still hasn't been.
July 31, 2014
On 7/30/2014 6:16 PM, Dicebot wrote:
> On Wednesday, 30 July 2014 at 23:50:51 UTC, H. S. Teoh via Digitalmars-d wrote:
>> But if you don't want to check ever to be removed, currently you have to
>> write:
>>
>>     if (!requiredCondition)
>>         assert(0); // compiler never removes this
>>
>> which IMO is relatively clear, and the use of assert(0) for forceful
>> termination is consistent with existing practice in D code.
>
> Not helping.
>
> ```
> import std.stdio;
>
> void foo()
> in { writeln("in contract"); }
> body { }
>
> void main() { foo(); }
> ```
>
> Compile with -release and check the output.

What do you expect to happen?
July 31, 2014
On 7/30/2014 4:51 PM, Tobias Müller wrote:
> With relatively 'dumb' compilers, this is not a big problem, but optimizers
> are more and more clever and will take profit of such assumptions if they
> can.

If D wishes to be competitive, it must go down that path.

If you, as a user, do not wish this behavior, then do not use -release.

The documentation for -release says:

"compile release version, which means not generating code for contracts and asserts. Array bounds checking is not done for system and trusted functions."

https://dlang.org/dmd-windows.html
July 31, 2014
On 7/31/2014 12:40 AM, David Bregman wrote:
> On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote:
>> I'd like to sum up my position and intent on all this.
>>
>> 1. I can discern no useful, practical difference between the notions of assume
>> and assert.
>
> People have explained the difference repeatedly, a ridiculous number of times
> now. Could you please take a minute to understand it this time instead of
> flippantly dismissing it again?
>
> assert does a runtime check, assume does not
> assume affects code generation/optimization, assert does not
> assert is for debugging, assume is not
> assume is for optimization, assert is not
>
> In terms of what they practically do, they have *nothing* in common, their
> functions are entirely orthogonal.

They are inextricably entangled. Consider:

   if (x == 0) abort();   // essentially what assert(x) does
   ... at this point, the optimizer knows, beyond doubt, that x!=0 ...
   if (x)  // optimizer can remove this check
      ...

which has the behavior of assume as you listed above, yet it is assert. We can pretend assert doesn't affect code, like we can pretend to have massless points in physics class, but in reality points have a mass and assert most definitely affects code generation, and does in every compiler I've checked, and it affects it in just the way the assume does.


> Still think there is no practical difference?

Yes.


>> 2. The compiler can make use of assert expressions to improve optimization,
>> even in -release mode.
>
> This will introduce a lot of undefined behavior, including making @safe code
> with asserts unsafe. I really think this needs to be acknowledged. As far as I
> can tell from the other thread, it still hasn't been.

I did acknowledge it for the array bounds case.

Note that your assume() will have the same effect, and worse, there will be no option to have the compiler insert a check, because then it would be an assert() and you might as well just use assert().

This is why I see the distinction as being pointless.
July 31, 2014
"Walter Bright"  wrote in message news:lrbpvj$mih$1@digitalmars.com...

> 5. assert(0); is equivalent to a halt, and the compiler won't remove it.

This is not the same definition the spec gives.  The spec says assert(0) can be treated as unreachable, and the compiler is allowed to optimize accordingly.

The difference is that in this code:

if (cond)
   assert(0);

With your above definition cond will be evaluated, while with the spec's more powerful definition it may be skipped.

July 31, 2014
On Thursday, 31 July 2014 at 07:47:51 UTC, Walter Bright wrote:
> On 7/30/2014 4:51 PM, Tobias Müller wrote:
>> With relatively 'dumb' compilers, this is not a big problem, but optimizers
>> are more and more clever and will take profit of such assumptions if they
>> can.
>
> If D wishes to be competitive, it must go down that path.
>
> If you, as a user, do not wish this behavior, then do not use -release.
>
> The documentation for -release says:
>
> "compile release version, which means not generating code for contracts and asserts. Array bounds checking is not done for system and trusted functions."
>
> https://dlang.org/dmd-windows.html

It's worth noting that ldc (and gdc maybe, can't remember) offer some finer control over what does/doesn't get eliminated, e.g. -enable-contracts -disable-asserts etc.
July 31, 2014
>>
>> In terms of what they practically do, they have *nothing* in common, their
>> functions are entirely orthogonal.
>
> They are inextricably entangled. Consider:
>
>    if (x == 0) abort();   // essentially what assert(x) does
>    ... at this point, the optimizer knows, beyond doubt, that x!=0 ...
>    if (x)  // optimizer can remove this check
>       ...

As far as I unterstand, this would be the behaviour without -release. With -release the code becomes

if(x)
    ...

and the optimizer cannot remove the (second) check. Or am I missing something?
July 31, 2014
On 7/31/2014 1:27 AM, Tobias Pankrath wrote:
>>>
>>> In terms of what they practically do, they have *nothing* in common, their
>>> functions are entirely orthogonal.
>>
>> They are inextricably entangled. Consider:
>>
>>    if (x == 0) abort();   // essentially what assert(x) does
>>    ... at this point, the optimizer knows, beyond doubt, that x!=0 ...
>>    if (x)  // optimizer can remove this check
>>       ...
>
> As far as I unterstand, this would be the behaviour without -release. With
> -release the code becomes
>
> if(x)
>      ...
>
> and the optimizer cannot remove the (second) check. Or am I missing something?

My intention is that the runtime check would be omitted, but the information would still be fed to the optimizer. This is not currently implemented.