Thread overview
Re: assert(false, "...") doesn't terminate program?!
Oct 27, 2012
Andrej Mitrovic
Oct 27, 2012
H. S. Teoh
Oct 27, 2012
Era Scarecrow
Oct 27, 2012
H. S. Teoh
Oct 27, 2012
Era Scarecrow
Oct 29, 2012
Don Clugston
Oct 29, 2012
Walter Bright
Oct 30, 2012
Don Clugston
Oct 30, 2012
Walter Bright
Oct 27, 2012
Andrej Mitrovic
October 27, 2012
On 10/27/12, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
>         writeln("how did the assert not trigger??!!");	// how did we get
> here?!

Maybe related to -release?

If the expression is not evaluable at compile-time the assert goes away when -release is used.
October 27, 2012
On Sat, Oct 27, 2012 at 08:26:21PM +0200, Andrej Mitrovic wrote:
> On 10/27/12, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
> >         writeln("how did the assert not trigger??!!");	// how did we get
> > here?!
> 
> Maybe related to -release?
[...]

Haha, you're right, the assert is compiled out because of -release.

But I disassembled the code, and didn't see the "auto x = 1/toInt()" either. Is the compiler optimizing that away?

Also, is that even a good idea? Shouldn't we be throwing an exception here instead of trying to trigger integer division by zero (which may not even terminate the program, depending on the OS, etc.)? Not to mention, the failure of this line to stop the program causes the code to return to the division function, which never terminates because of the zero divisor.


T

-- 
The volume of a pizza of thickness a and radius z can be described by the following formula: pi zz a. -- Wouter Verhelst
October 27, 2012
On 10/27/12, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
> Shouldn't we be throwing an exception
> here instead of trying to trigger integer division by zero

I was gonna say "quickfur made a pull" before realizing it's you https://github.com/D-Programming-Language/phobos/pull/902
October 27, 2012
On Saturday, 27 October 2012 at 18:36:57 UTC, H. S. Teoh wrote:
> On Sat, Oct 27, 2012 at 08:26:21PM +0200, Andrej Mitrovic wrote:
>> Maybe related to -release?
>
> Haha, you're right, the assert is compiled out because of -release.

 Then it is a bug; Unless perhaps it is inside a contract (in/out) or debug statement.

 TDPL pg 326:
[quote]
 An assertion against a constant that is known to be zero during compilation, such as assert(false), assert(0), or assert(null), behaves a tad differently from a regular assert.

 In non-release mode, assert(false) does not do anything special: It just throws an AssertError exception.

 In release mode, however, assert(false) is NOT compiled out of existence; it will always cause a program to stop. This time, however, there would be no exception and no chance of continuing to run after an assert(false) was hit. The program will CRASH.
[/quote]

October 27, 2012
On Sat, Oct 27, 2012 at 09:03:05PM +0200, Era Scarecrow wrote:
> On Saturday, 27 October 2012 at 18:36:57 UTC, H. S. Teoh wrote:
> >On Sat, Oct 27, 2012 at 08:26:21PM +0200, Andrej Mitrovic wrote:
> >>Maybe related to -release?
> >
> >Haha, you're right, the assert is compiled out because of -release.
> 
>  Then it is a bug; Unless perhaps it is inside a contract (in/out)
> or debug statement.

No it's not a bug, because the value is *not* known to be zero at compile-time (it depends on what value you put in the BigInt).


>  TDPL pg 326:
> [quote]
>  An assertion against a constant that is known to be zero during
> compilation, such as assert(false), assert(0), or assert(null),
> behaves a tad differently from a regular assert.
[...]


T

-- 
Ph.D. = Permanent head Damage
October 27, 2012
On Saturday, 27 October 2012 at 19:08:02 UTC, H. S. Teoh wrote:
> No it's not a bug, because the value is *not* known to be zero at compile-time (it depends on what value you put in the BigInt).

 I think I read the question wrong earlier. My apologies.
October 29, 2012
On 27/10/12 20:39, H. S. Teoh wrote:
> On Sat, Oct 27, 2012 at 08:26:21PM +0200, Andrej Mitrovic wrote:
>> On 10/27/12, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
>>>          writeln("how did the assert not trigger??!!");	// how did we get
>>> here?!
>>
>> Maybe related to -release?
> [...]
>
> Haha, you're right, the assert is compiled out because of -release.
>
> But I disassembled the code, and didn't see the "auto x = 1/toInt()"
> either. Is the compiler optimizing that away?

Yes, and I don't know on what basis it thinks it's legal to do that.

> Also, is that even a good idea? Shouldn't we be throwing an exception
> here instead of trying to trigger integer division by zero (which may
> not even terminate the program, depending on the OS, etc.)?

The intention was that it should behave _exactly_ like an integer division by zero.

It's bug 8021, BTW.
October 29, 2012
On 10/29/2012 7:51 AM, Don Clugston wrote:> On 27/10/12 20:39, H. S. Teoh wrote:
>> On Sat, Oct 27, 2012 at 08:26:21PM +0200, Andrej Mitrovic wrote:
>>> On 10/27/12, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
>>>>          writeln("how did the assert not trigger??!!");    // how did we get
>>>> here?!
>>>
>>> Maybe related to -release?
>> [...]
>>
>> Haha, you're right, the assert is compiled out because of -release.
>>
>> But I disassembled the code, and didn't see the "auto x = 1/toInt()"
>> either. Is the compiler optimizing that away?
>
> Yes, and I don't know on what basis it thinks it's legal to do that.

Because x is a dead assignment, and so the 1/ is removed. Divide by 0 faults are not considered a side effect. I think the code would be better written as:

    if (toInt() == 0) throw new Error();

If you really must have a divide by zero fault,

    if (toInt() == 0) divideByZero();

where:

    void divideByZero()
    {
         static int x;
         *cast(int*)0 = x / 0;
    }

October 30, 2012
On 29/10/12 18:38, Walter Bright wrote:
> On 10/29/2012 7:51 AM, Don Clugston wrote:> On 27/10/12 20:39, H. S.
> Teoh wrote:
>  >> On Sat, Oct 27, 2012 at 08:26:21PM +0200, Andrej Mitrovic wrote:
>  >>> On 10/27/12, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
>  >>>>          writeln("how did the assert not trigger??!!");    // how
> did we get
>  >>>> here?!
>  >>>
>  >>> Maybe related to -release?
>  >> [...]
>  >>
>  >> Haha, you're right, the assert is compiled out because of -release.
>  >>
>  >> But I disassembled the code, and didn't see the "auto x = 1/toInt()"
>  >> either. Is the compiler optimizing that away?
>  >
>  > Yes, and I don't know on what basis it thinks it's legal to do that.
>
> Because x is a dead assignment, and so the 1/ is removed.


> Divide by 0 faults are not considered a side effect.

Ah, that's interesting, I didn't know that.



I think the code would be
> better written as:
>
>      if (toInt() == 0) throw new Error();
>
> If you really must have a divide by zero fault,
>
>      if (toInt() == 0) divideByZero();
>
> where:
>
>      void divideByZero()
>      {
>           static int x;
>           *cast(int*)0 = x / 0;
>      }

And that works because writes to 0 _are_ considered a side-effect?
Is that guaranteed to work?


October 30, 2012
On 10/30/2012 5:53 AM, Don Clugston wrote:
> > I think the code would be
>> better written as:
>>
>>      if (toInt() == 0) throw new Error();
>>
>> If you really must have a divide by zero fault,
>>
>>      if (toInt() == 0) divideByZero();
>>
>> where:
>>
>>      void divideByZero()
>>      {
>>           static int x;
>>           *cast(int*)0 = x / 0;
>>      }
>
> And that works because writes to 0 _are_ considered a side-effect?
> Is that guaranteed to work?

Writing through a pointer is considered a side effect.