July 31, 2014
On 7/30/2014 3:53 PM, Artur Skawina via Digitalmars-d wrote:
> No, with the assert definition you're proposing, it won't. It would
> be allowed to optimize away the bounds check. And this is just one of
> many problems with the assert==assume approach.

Please explain how assume would behave any differently.

July 31, 2014
Walter Bright <newshound2@digitalmars.com> wrote:
> On 7/30/2014 3:53 PM, Artur Skawina via Digitalmars-d wrote:
>> No, with the assert definition you're proposing, it won't. It would be allowed to optimize away the bounds check. And this is just one of many problems with the assert==assume approach.
> 
> Please explain how assume would behave any differently.

It wouldn't and that's the point.
If you have (a more harmless) assert _and_ assume you can still use assert,
which would then _not_ allow those optimization.

Tobi
July 31, 2014
On 07/31/14 02:31, Walter Bright via Digitalmars-d wrote:
> On 7/30/2014 3:53 PM, Artur Skawina via Digitalmars-d wrote:
>> No, with the assert definition you're proposing, it won't. It would be allowed to optimize away the bounds check. And this is just one of many problems with the assert==assume approach.
> 
> Please explain how assume would behave any differently.

I'm not arguing for assume [1], just against allowing information
derived from assert expressions being able leak and affect other
parts of the program. That just can not work (sanely); it would
cause more problems than C's undefined behavior abuse. Because
the UB triggers are well defined - by the language - and relatively
well known. Asserts are /user-defined/. One wouldn't be able to
reason about code without considering every single assert expression
that was evaluated before reaching the current expression/function.
An incorrect or inexact assert() hidden away somewhere could silently
affect unrelated code, disable important safety checks etc.

artur

[1] I don't think that introducing `assume` would make a significant difference at this point - there are many more important D issues needing attention... But it could be done, would need to be @system, and probably wouldn't require much work. In fact, it already exists in gdc-ese, kind of:

   static import gcc.attribute;
   enum inline = gcc.attribute.attribute("forceinline");

   @inline void assume()(bool c) {
      import gcc.builtins;
      if (!c)
         __builtin_unreachable();
   }

   bool plain_assert(int i) {
      assert(i<6);
      return i==9;
   }
   // => "cmpl $9, %edi; sete %al; ret"

   bool assume_instead_of_assert(int i) {
      assume(i<6);
      return i==9;
   }
   // => "xorl %eax, %eax; ret"


`assume`, unlike `assert`, may affect codegen.

July 31, 2014
On 7/30/2014 5:50 PM, Tobias Müller wrote:
> Walter Bright <newshound2@digitalmars.com> wrote:
>> On 7/30/2014 3:53 PM, Artur Skawina via Digitalmars-d wrote:
>>> No, with the assert definition you're proposing, it won't. It would
>>> be allowed to optimize away the bounds check. And this is just one of
>>> many problems with the assert==assume approach.
>>
>> Please explain how assume would behave any differently.
>
> It wouldn't and that's the point.

So we're back to assert and assume being the same thing. Ok.

July 31, 2014
Am 31.07.2014 02:50, schrieb Tobias Müller:
> Walter Bright <newshound2@digitalmars.com> wrote:
>> On 7/30/2014 3:53 PM, Artur Skawina via Digitalmars-d wrote:
>>> No, with the assert definition you're proposing, it won't. It would
>>> be allowed to optimize away the bounds check. And this is just one of
>>> many problems with the assert==assume approach.
>>
>> Please explain how assume would behave any differently.
>
> It wouldn't and that's the point.
> If you have (a more harmless) assert _and_ assume you can still use assert,
> which would then _not_ allow those optimization.
>
> Tobi
>

I'm in favor of a "harmless" assert().
In C(++) I sometimes use things like

assert(x != NULL);

if(x != NULL) {
	x->foo = 42;
	// ...
}

I have that assertion to hopefully find bugs during development and fix them. However, no program is bug free and so it's totally possible that x *is* NULL in some circumstance in the wild (in a "release" mode binary), so I want to make sure it doesn't explode if that happens but handle the problem more gracefully.

It would be rather unfortunate if the compiler removed that second check in release mode because the assertion made it assume that x can't be NULL.

Cheers,
Daniel


July 31, 2014
On 07/31/14 02:12, Andrei Alexandrescu via Digitalmars-d wrote:

> I think bounds checking is an intrinsic feature of the language, not something easily configurable.

The problem is with asserts that cause the runtime checks to be eliminated. An simple assert would be enough to bypass @safe.

artur
July 31, 2014
On 7/30/2014 6:38 PM, Daniel Gibson wrote:
> I'm in favor of a "harmless" assert().
> In C(++) I sometimes use things like
>
> assert(x != NULL);
>
> if(x != NULL) {
>      x->foo = 42;
>      // ...
> }
>
> I have that assertion to hopefully find bugs during development and fix them.
> However, no program is bug free and so it's totally possible that x *is* NULL in
> some circumstance in the wild (in a "release" mode binary), so I want to make
> sure it doesn't explode if that happens but handle the problem more gracefully.
>
> It would be rather unfortunate if the compiler removed that second check in
> release mode because the assertion made it assume that x can't be NULL.

Your code is doomed to having problems using assert this way.

The behavior you desire here is easily handled by creating your own template to exhibit it. See the implementation of enforce() for how to do it.

July 31, 2014
On Thursday, 31 July 2014 at 02:53:11 UTC, Walter Bright wrote:
> Your code is doomed to having problems using assert this way.
>
> The behavior you desire here is easily handled by creating your own template to exhibit it. See the implementation of enforce() for how to do it.

When is the appropriate time to use an assert? If an assert
should not be used on input, then any thing that can't be
statically known is considered an input and anything that is
derived from an input is also an input... so when can we use an
assert? The only things left it seems are things know at compile
time and at that point what is the the point of having assert
when we have static assert...
July 31, 2014
Walter Bright:

> That's a good point. You could reasonably argue that such an optimization should not happen.

I agree. Turning D assert() in a kind of a assert-assume hybrid will be a mistake.


>> I think you are still missing the essential difference between assume and assert.
>
> How does assume improve the situation?

I didn't ask for an assume in this thread. See what I am asking for:

http://forum.dlang.org/thread/jrxrmcmeksxwlyuitzqp@forum.dlang.org?page=22#post-kjqjompjdhmbmzyhbzbb:40forum.dlang.org

The answer I've given to Andrei is generic, but I can give more details.

Bye,
bearophile
July 31, 2014
Walter Bright:

> So we're back to assert and assume being the same thing. Ok.

They aren't, and they shouldn't be, regardless the number of times you say they are.

Bye,
bearophile