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.