On 08/01/2014 01:53 PM, Don wrote:
On Friday, 1 August 2014 at 09:02:36 UTC, Walter Bright wrote:
On 7/31/2014 11:24 PM, "Ola Fosheim Grøstad"
<ola.fosheim.grostad+dl...@gmail.com>" wrote:
On Friday, 1 August 2014 at 02:44:51 UTC, Walter Bright wrote:
That entry makes no mention of assert being used as an optimization
hint.
Saying that a predicate is always true means it's available to the
optimizer.
An assert does not say that the predicate is always true.
Yes, it does. From Meyers' comprehensive tome on the topic
"Object-Oriented Software Construction" (1997) where he writes:
"A run-time assertion violation is the manifestation of a bug in the
software."
-- pg. 346
In fact, Meyers calls it "rule (1)" of assertions.
I would rephrase it as: "An assert says that either the predicate
is always true, or else the program is in an invalid state and will not
operate correctly".
...
Bertrand _Meyer_ is not a furious proponent of undefined behaviour. He
is not exactly a fan of C or C++ either and an expressed opponent of the
typical 'C hacker' attitude.
But I do think this entire argument seems to me to be rather misplaced.
I think it's really it's about -release, not about assert().
The arguments presented by Ola et al mostly seem to be arguments against
the use of the -release switch. Because it is a very dangerous flag.
If you're removing all your asserts I'd say you're playing a dangerous
game already.
Sure, and it is /obviously/ perfectly fine to e.g. kill a tightrope
walker, so this should not be prosecuted.
If an assert would have failed, but execution continued
anyway, you're in undefined behaviour
No. For the purpose of (maybe remote!) debugging, the programmer wants
the behaviour to be _the one that the program specifies_, even if it is
not the one that he _expected_.
-- at the very least, you're in a
condition that the programmer believed could never happen.
...
Yes, a condition that _some_ programmer believed could never happen. It
is not even a given that this condition is not actually created
somewhere and handled somewhere else, especially as software evolves.
If you are disabling your asserts, but still believe that they may fail,
that means you're expecting your program to enter undefined behaviour!
Nonsense. This claim is ignoring the current reality of software
development. One would be expecting one's program to be buggy, but one
would still think that _almost all_ assertions pass always and those
that don't would be expected to pass _almost always_. How many pieces of
non-trivial bug-free software did you write or _were required to work on
without full knowledge about the code base_?
In any case if one is _disabling_ one's asserts, one doesn't expect them
to have any kind of effect whether they may fail or not.
That seems to be a rather illogical position.
It was constructed to seem to be. For example, the expectation that some
asserts are wrong was conveniently replaced by the expectation that all
(or at least a murkily unspecified amount of) asserts are wrong and the
existence of trade-offs was ignored. This is simply a straw man used to
defend an indefensible position.
I think very strongly that we should rename the "-release" switch,
especially if we do start to make use of asserts. It's going to cause no
end of confusion and passionate debate.
---
Disabling assertions and contracts and using them for optimization
should be distinct options.
In one of the 2013 DConf talks a lint tool was discussed that disallowed
you from you writing a condition that was provably impossible based on
'in' contracts.
eg:
void foo( int x)
in{
assert(x > 6);
}
body {
if (x > 2) // ERROR! This is always true!
...
}
Which is an interesting approach.
By definition, any optimisations that are performed on the basis of an
assert() that could affect control flow, are detectable with 100%
accuracy by a lint tool.
By a family of lint tools indexed by the respective compiler back-ends.
Furthermore, you have to understand all of those back-ends and all their
passes completely and you need to track how information relating
possible optimizations flows through them. You will not write all those
lints in a lifetime and you need to start this undertaking again
whenever someone writes a new back-end and you need to always keep the
lints in sync with the back-ends (and maybe, front-ends). Besides, it is
an incredibly complex solution for a completely trivial issue.
And so, if you wanted to remove all your
asserts but were worried about this issue, it's detectable at compile time.
This issue does not only affect people who are worried about it (and I'd
guess the truth is way closer to the opposite), and in fact you yourself
claimed above that it only affects people who are not worried about
undefined behaviour. This is a rather illogical position to be in, even
if both of the contradicting claims are not true statements. (Sorry!
Couldn't resist! :-) )
In any case, please don't ignore existing complexity in order to make
claims that seem pragmatic.