August 03, 2014
On Saturday, 2 August 2014 at 19:10:51 UTC, Walter Bright wrote:
> On 8/2/2014 4:12 AM, Artur Skawina via Digitalmars-d wrote:
>> _`assume` is extremely dangerous_. Redefining `assert` to include `assume`
>> would result in D's `assert` being banned from the whole code base, if 'D'
>> even would be consider a 'sane' enough language to use...
>
> More simply, you could just ban "-release".
>
> Keep in mind, that under the current implementation, removing asserts also removes the bug checking that the asserts presumably were inserted for. If the asserts don't hold true, the program has undetected bugs in it, it is in an unknown and invalid state, and the ability to predict what it will do next is gone.
>
> I.e. you should already have banned use of "-release".

There's a huge difference between removing an extra check to verify the lack of a bug versus guaranteeing the lack of a bug and optimizing off of it. The way that assert is traditionally used (C/C++, Java, C#, current D implementation, etc) is a verification of your code, not a hint to the optimizer that some expression is true. If D wishes to change this meaning then it goes against D's philosophy of that if C code compiles it should behave the same way as it did in C, and goes against every previous usage of assert. Worse, it does so in a way that would be extremely hard to detect if tests don't catch it since the error would occur in an unrelated location and only in release builds.

More importantly, it's a huge security flaw. Not all bugs are equal; an assertion being false means a bug exists, but optimizing based off of this allows much more severe bugs to exist. Given a function that makes a call to a database/launches a process/returns some HTML/etc, having an early check that directly or indirectly asserts the data is valid to ease debugging will remove the runtime check that ensures there's nothing malicious in that data. Now because you had one extra assert, you have a huge security flaw and a great deal of unhappy customers that have had their accounts compromised or their information leaked. This is not an unrealistic scenario.

That being said, so long as this is a separate optimization switch, it should rarely be an issue. Keep the current behaviour of -release disabling asserts, then add a new -assumeasserts or -Oassert or such that allows the optimizer to optimize with the guarantee that all asserts are true. It would also be good to be able to guarantee that some piece of code can never be optimized out (e.g., sanitation of user input). Changing the current behaviour of -release is a huge breaking change that would open up security holes and overall I feel would be a terrible thing to do.
August 03, 2014
On Saturday, 2 August 2014 at 20:04:32 UTC, Johannes Pfau wrote:
> Am Sat, 02 Aug 2014 12:19:41 -0700
> schrieb Walter Bright <newshound2@digitalmars.com>:
>
>> On 8/2/2014 6:20 AM, Artur Skawina via Digitalmars-d wrote:
>> > The bug was _introduced_ by the assert, the code was 100% correct.
>> 
>> Asserts are part of the code, and writing incorrect asserts is
>> writing buggy code.
>> 
>
> And you still think that changing the behavior of assert is a good
> idea? Even if assert was always meant to work like this, even if the
> spec clearly defined it this will be a PR disaster. People don't care
> what was in the spec, the only thing they know is the code worked
> before, now it doesn't work anymore ==> blame it on the
> compiler/language.

I don't buy this!

JoeCoder: "Boss, I'm not able to run my code with without -release in development, because every few milliseconds an assert is triggered, but with that switch used to be very fast apart some crash and silly behaviour from time to time in production. But now I've upgraded the compiler and the bad boy working on the D language has ruined all my work!"

Boss:"Stick with the old compiler version, light more candles in the Charles Babbage Altar, and you are sacked!"

> Just envision the situation when somebody post on reddit 'My code has
> been broken by this compiler release' then spents quite some
> time to track it down and complains about the assert changes? Will you
> then reply 'You're code was broken anyway'?

This should be a big YES.

> What about Scott Meyers basically telling us that we should make the
> language 'predictable' for the users? Doesn't the existence and size of
> this discussion already prove that making assert work like assume will
> be unexpected for many people? You even admitted that in other
> languages assert has a different meaning. You argued against the name
> 'volatile' cause it has a different meaning in other languages. How
> does this not apply to assert/assume? You might ask for Scotts opinion
> about this case if you don't believe the people in this thread.

I understand the debate of introducing assume, and keep the two face of the medal split, but I think that there's nothing not predictable in the fact that, if an assert is there, everyone ranging from the optimiser to the colleague reading the sources is expecting that the expression must be true, without doubt. That's the predictable behaviour.

---
Paolo


August 03, 2014
On Saturday, 2 August 2014 at 22:00:27 UTC, Andrew Godfrey wrote:
> On Saturday, 2 August 2014 at 21:36:11 UTC, Tobias Pankrath wrote:
>> On Saturday, 2 August 2014 at 21:25:40 UTC, Ola Fosheim Grøstad wrote:
>>> On Saturday, 2 August 2014 at 20:27:09 UTC, Andrei Alexandrescu wrote:
>>>> Hmmm... code that fails assertions is hardly working. -- Andrei
>>>
>>> It is not the code that fails the assertion, it is the asserted proposition that has not be satisfied by the axioms in the program as it has been formulated in the context. It does not mean "can not be satisfied", but "has not been satisfied".
>>
>> Don't you agree, that a program that throws AssertError in non -release* build is broken?
>>
>> * this is not the opposite of debug
>
> By this definition of 'broken', I assert that most shipped software is broken.

I strongly disagree with that: if there's pressure for a release, most software in that condition has the assert _removed_ or _commented_, a bug opened, and a boss directive to do so so that it's boss responsibility having taken the risk.

The assert is _reinserted_ or _uncommented_ when there's someone hunting for that bug after the release.

If this operation can't be done because the failing asserts are a bazillion, compiling it in '-release' with the proposed assert/assume semantic don't change anything: from time to time, when the snowball of failed assert-optimisations will start to destroy the program logic, all that thing will explode in the face of the user.
---
Paolo
August 03, 2014
On Sunday, 3 August 2014 at 04:29:28 UTC, Kapps wrote:
> On Saturday, 2 August 2014 at 19:10:51 UTC, Walter Bright wrote:
>> On 8/2/2014 4:12 AM, Artur Skawina via Digitalmars-d wrote:
>
> More importantly, it's a huge security flaw. Not all bugs are equal; an assertion being false means a bug exists, but optimizing based off of this allows much more severe bugs to exist. Given a function that makes a call to a database/launches a process/returns some HTML/etc, having an early check that directly or indirectly asserts the data is valid to ease debugging will remove the runtime check that ensures there's nothing malicious in that data. Now because you had one extra assert, you have a huge security flaw and a great deal of unhappy customers that have had their accounts compromised or their information leaked. This is not an unrealistic scenario.

The costumer should not be happy because an assert was used for that...

---
Paolo
August 03, 2014
On 08/03/14 06:29, Kapps via Digitalmars-d wrote:
> Not all bugs are equal; an assertion being false means a bug exists, but optimizing based off of this allows much more severe bugs to exist.

Yes.

Giving a new meaning to `assert` would also affect how it's used. Asserts would be used not only to check and document assumptions, but also to enable certain optimizations. This would add a new source of bugs. A harmless i-think-this-is-always-true assert would be indistinguishable from a potentially dangerous one. The former kind does not really need much attention, the latter requires special care and needs to be looked after even when it's not failing.


> Keep the current behaviour of -release disabling asserts, then add a new -assumeasserts or -Oassert

The problem with this is that it introduces a new dialect in which `assert` has a different meaning. If parts of a program are (or were) independently developed by different teams, one using asserts the traditional way (for debugging) and another using them aggressively to expose every optimization opportunity, then the debugging asserts which were supposed to be harmless will be reinterpreted. Effectively you would always have to assume that assert==assume. So a compiler switch wouldn't really improve the situation.

artur
August 03, 2014
On 08/02/2014 11:36 PM, Tobias Pankrath wrote:
> On Saturday, 2 August 2014 at 21:25:40 UTC, Ola Fosheim Grøstad wrote:
>> On Saturday, 2 August 2014 at 20:27:09 UTC, Andrei Alexandrescu wrote:
>>> Hmmm... code that fails assertions is hardly working. -- Andrei
>>
>> It is not the code that fails the assertion, it is the asserted
>> proposition that has not be satisfied by the axioms in the program as
>> it has been formulated in the context. It does not mean "can not be
>> satisfied", but "has not been satisfied".
>
> Don't you agree, that a program that throws AssertError in non -release*
> build is broken?
>...

According to you, what does it mean for a program to be 'broken'?

- Is being 'broken' a binary property or can there be different shades of 'broken'?

- Is it possible to break 'broken' software more than it was 'broken' already?

- Is it fine to break 'broken' software in this way?

- Should people be allowed to release 'broken' software? Are they?

- Can 'broken' software be useful?

- Would _you_ use software you know that is 'broken'?

etc. Maybe you find other questions you can answer to exemplify what 'broken' is supposed to mean.
August 03, 2014
On 08/03/2014 11:15 AM, Paolo Invernizzi wrote:
> because every few milliseconds an assert is triggered

Right, and software does not have security holes because otherwise they would obviously be exploited every few milliseconds during in-house testing.

> the colleague reading the sources is expecting that the expression must be true, without doubt.

Poor guy. Do you support the claim that he might, if he supports your "I don't buy this!" post introduce new assertions by conjecturing they are true and then running the program for a few milliseconds?
August 03, 2014
On Sunday, 3 August 2014 at 10:49:39 UTC, Timon Gehr wrote:
> On 08/03/2014 11:15 AM, Paolo Invernizzi wrote:
>> because every few milliseconds an assert is triggered
>
> Right, and software does not have security holes because otherwise they would obviously be exploited every few milliseconds during in-house testing.

That is a totally different matter: security holes are about things that the programmer is _totally missing_, and someone is seeing and exploiting that. I don't see how that relate with the present discussion.

>> the colleague reading the sources is expecting that the  expression must be true, without doubt.
>
> Poor guy. Do you support the claim that he might, if he supports your "I don't buy this!" post introduce new assertions by conjecturing they are true and then running the program for a few milliseconds?

I don't grasp what you are arguing here: can you rephrase please?
---
Paolo
August 03, 2014
On 08/03/2014 03:01 PM, Paolo Invernizzi wrote:
> On Sunday, 3 August 2014 at 10:49:39 UTC, Timon Gehr wrote:
>> On 08/03/2014 11:15 AM, Paolo Invernizzi wrote:
>>> because every few milliseconds an assert is triggered
>>
>> Right, and software does not have security holes because otherwise
>> they would obviously be exploited every few milliseconds during
>> in-house testing.
>
> That is a totally different matter:

Well, no.

> security holes are about things that
> the programmer is _totally missing_,

The programmer(s!) may be _totally missing_ the conditions that lead to an assertion failure. In fact, unless assertions are intentionally misused, this is always the case.

> and someone is seeing and exploiting that.

(Undefined behaviour introduced in this way may be exploitable.)

> ...  can you rephrase please?

If wrong assertions would indeed fail every few milliseconds, then a way to show an assertion to be correct beyond reasonable doubt is to add the test of the condition to the program and then run it for a few milliseconds.
August 03, 2014
On Sunday, 3 August 2014 at 14:10:29 UTC, Timon Gehr wrote:
> On 08/03/2014 03:01 PM, Paolo Invernizzi wrote:
>> On Sunday, 3 August 2014 at 10:49:39 UTC, Timon Gehr wrote:
>>> On 08/03/2014 11:15 AM, Paolo Invernizzi wrote:
>>>> because every few milliseconds an assert is triggered
>>>
>>> Right, and software does not have security holes because otherwise
>>> they would obviously be exploited every few milliseconds during
>>> in-house testing.
>>
>> That is a totally different matter:
>
> Well, no.
>
>> security holes are about things that
>> the programmer is _totally missing_,
>
> The programmer(s!) may be _totally missing_ the conditions that lead to an assertion failure. In fact, unless assertions are intentionally misused, this is always the case.
>
>> and someone is seeing and exploiting that.
>
> (Undefined behaviour introduced in this way may be exploitable.)

If the assertion triggers, that's not undefined behaviour: it's a bug, already implanted in the code, that the assertion is surfacing _avoiding_ undefined behaviour occurring from the really next line of code.

Security holes are not related to assertions at all, they are related in unpredictable state that the program has reached, outside of the view of the programmers.

Assertions are only checks that the reasoning about the flow and the conditions is going in the way that was originally intended. If you have failures, and you want to cope with them, you MUST remove the failing assertions from the code, and turn them in specific code to cope with the faulty condition.

Something like 'warning mate! the commented assertion is triggered from time to time, so there's definitely something somewhere in the code that we not fully understand, so here below is a dirty trick to turn the program logic back on the rails because we are in a hurry'.

I've never seen a live assertion in the code without the intended behaviour of the expression being true: what would be a mess otherwise!

>> ...  can you rephrase please?
>
> If wrong assertions would indeed fail every few milliseconds, then a way to show an assertion to be correct beyond reasonable doubt is to add the test of the condition to the program and then run it for a few milliseconds.

That was a stereotypical example; what I was trying to argue it's that also if we do some dirty tricks to keep the train on the rails, if the program logic is flowed you can have an avalanche effect in some cases: everything seems to work fine for a good amount of time until the snowball comes down,  violates catastrophically the program logic and boom.

In that cases, also going with '-release' keeping the fingers crossed it's not a good solutions at all.

---
Paolo