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