assert semantic change proposal

via Digitalmars-d digitalmars-d at puremagic.com
Wed Aug 6 03:13:49 PDT 2014


On Wednesday, 6 August 2014 at 01:11:55 UTC, Jeremy Powers via 
Digitalmars-d wrote:
>> That's in the past. This is all about the pros and cons of 
>> changing it now
>> and for the future.
>>
>
> The main argument seems to revolve around whether this is 
> actually a change
> or not.  In my (and others') view, the treatment of assert as 
> 'assume' is
> not a change at all.  It was in there all along, we just needed 
> the wizard
> to tell us.

This is already the first misunderstanding: The argument is about 
whether it's a good idea, not whether it's newly introduced or 
has been the intended meaning since assert's conception.

>
>
>
> The below can safely be ignored, as I just continue the pedantic
> discussions....
>
>
> OK, but my point was you were using a different definition of 
> undefined
>> behavior. We can't communicate if we aren't using the same 
>> meanings of
>> words.
>>
>>
> Yes, very true.  My definition of undefined in this case hinges 
> on my
> definition of what assert means.  If a failed assert means all 
> code after
> it is invalid, then by definition (as I interpret the 
> definition) that code
> is invalid and can be said to have undefined behaviour.  That 
> is, it makes
> sense to me that it is specified as undefined, by the spec that 
> is
> incredibly unclear.  I may be reading too much into it here, 
> but this
> follows the strict definition of undefined - it is undefined 
> because it is
> defined to be undefined.  This is the 'because I said so' 
> defense.

Of course you can define your own concept and call it 
"undefined", but I don't see how it matters. The concept 
described by the usual definition of "undefined" still exists, 
and it still has very different implications than your concept 
has. To give a more practical example:

You're writing an authentication function. It takes a username 
and a password, and returns true or false, depending on whether 
the password is correct for this username. Unfortunately, the 
verification algorithm is wrong: due to an integer overflow in 
the hash calculation, it rejects some valid passwords, but never 
accepts invalid ones. The program is clearly incorrect, but its 
behaviour is still well-defined and predictable (overflow is not 
undefined in D).

Now, if the flaw in the algorithm were due to an actual undefined 
operation, everything could happen, including the function 
accepting invalid passwords. I hope it's clear that this is a 
very different class of brokenness.

> My stance is that this new/old definition is a good thing, as 
> it matches
> how I thought things were already, and any code that surfaces 
> as broken
> because of it was already broken in my definition.  Therefore 
> this 'change'
> is good, does not introduce breaking changes, and arguments 
> about such
> should be redirected towards mitigation and fixing of 
> expectations.
>
> In an attempt to return this discussion to something useful, 
> question:
>
> If assert means what I think it means (and assuming we agree on 
> what the
> actual two interpretations are), how do we allay concerns about 
> it?  Is
> there anything fundamentally/irretrievably bad if we use this 
> new/old
> definition?  (Can we programmatically (sp?) identify and 
> flag/resolve
> issues that occur from a mismatch of expectations?)

My understanding (which is probably the same as that of most 
people participating in the discussion, because as I said above, 
I _don't_ think the argument is about a misunderstanding on this 
level):

Walter's assert:
* Expresses a statement that the programmer intends to be true. 
It is only checked in non-release mode.
* The compiler can assume that it is true - even in release mode 
- because the programmer explicitly said so, and the compiler may 
not have figured it out by itself (similar to casts, which also 
express assumptions by the programmer that the compiler cannot 
know otherwise).
* Asserting a condition that is false is undefined behaviour.

The other assert:
* Expresses a statement that the programmer intends to be true. 
It is only checked in non-release mode.
* Because it is unlikely that the programmer has proved the 
correctness in the general case, the compiler must not assume it 
is true unless it can prove it to be, either at compile time, or 
with a runtime check. Release mode disables the runtime checks.
* Asserting a condition that is false either raises an error at 
runtime, aborts compilation, or doesn't do anything. It never 
causes undefined behaviour by itself.

As I already wrote elsewhere, an assert with the 
suggested/intended behaviour is a very dangerous tool that should 
not be used as widely as it is today. If the asserted condition 
is wrong (for whatever reason), it would create not just wrong 
behaviour, but undefined behaviour (as described above, not your 
concept).

H.S. Teoh however suggested to extend compile time checking for 
assertions. I believe this is the way to go forward, and it has 
great potential. What I don't agree with, of course, is to just 
believe anything in the assertions to be true without verifying 
it.


More information about the Digitalmars-d mailing list