On 7/31/2014 4:36 AM, bearophile wrote:
(The problem is that your have defined your own idea,

"My" idea is the conventional one for assert - see the Wikipedia entry on it.

  -- http://en.wikipedia.org/wiki/Assertion_(software_development)

Yes, that article also says: "Under abnormal conditions, disabling assertion checking can mean that a program that would have aborted will continue to run. This is sometimes preferable." The last statement is in contradiction with the rest of the article, and I don't agree with it.


so what I can show you
will look meaningless or not comformant to your own definition. So this
discussion is going nowhere. And my original topic drowns in this assume/assert
debate that is off-topic.)


In the case of assume:


int max(in int x, in int y) {
     assume(x > y);
     return (x > y) ? x : y;
}

The optimizer is free to replace that code with this, even in debug builds:

int max(in int x, in int y) {
     return x;
}

That implies that the behavior is undefined if the assumption is false. A compiler is free to add checks for undefined behavior (you yourself are a huge proponent of this) and people would (very reasonably for a quality implementation) expect that the assumption is checked. Hence, it will behave like assert.


In the case of assert:

int max(in int x, in int y) {
     assert(x > y);
     return (x > y) ? x : y;
}


In debug builds gets rewritten as:

int max(in int x, in int y) {
     if (x <= y)
         throw new AssertError("...");
     return x;
}

Note how that behaves like assume.


And in release builds gets rewritten as:

int max(in int x, in int y) {
     return (x > y) ? x : y;
}

To require that the code be valid with x>y is to misunderstand what contract programming is all about. An assert is a contract and must be valid, whether it is checked or not. -release is not to be used to deliberately change the semantics of code.

For example, from the wikipedia article:

"Assertions are distinct from routine error-handling. Assertions document logically impossible situations and discover programming errors: if the impossible occurs, then something fundamental is clearly wrong. This is distinct from error handling: most error conditions are possible, although some may be extremely unlikely to occur in practice. Using assertions as a general-purpose error handling mechanism is unwise: assertions do not allow for recovery from errors; an assertion failure will normally halt the program's execution abruptly."

Note "LOGICALLY IMPOSSIBLE SITUATIONS", uppercased for emphasis. These are not my weird unique made-up-on-the-spot out-of-step ideas.

Code that relies on assertions being false is semantically broken.

In closing, Hoare's paper:

   http://sunnyday.mit.edu/16.355/Hoare-CACM-69.pdf

speaks of "assertions" which can be proven to be true. (It doesn't mention "assumptions".) The simplest way to prove it is to put in a runtime check. D's assert() nicely fits in with that.

Reply via email to