Making AssertError a singleton
Andrei Alexandrescu via Digitalmars-d
digitalmars-d at puremagic.com
Tue Dec 13 10:05:18 PST 2016
On 12/13/2016 12:18 PM, Timon Gehr wrote:
> I assume you don't refer to passing along a runtime flag whether
> execution is currently in a contract and then selectively disable
> calling of dtors.
No, something simpler than that - nontransitive. Consider:
T fun(R range)
in
{
assert(range.front == 42);
}
body
{
...
}
Here, the assert keyword present straight in the contract has a distinct
meaning from the assert present transitively in code invoked by the
contract. If the assert in the contract fails, that's the contract not
passing. Assume Range.front() has e.g. assert(!empty) inside, that's a
different kind of failure - in this case it may arguably be a bug in the
contract definition.
> So I think you are suggesting a breaking change in language semantics:
>
> void myAssert(bool x){
> // this function could be in a different compilation unit
> assert(x);
> }
>
> class C{
> void foo(int a)in{
> myAssert(a>0);
> }body{
>
> }
> }
> class D:C{
> override void foo(int a)in{
> myAssert(a<0);
> }body{
>
> }
> }
>
> void main(){
> D d = new D;
> d.foo(1);
> d.foo(-1);
> }
Yah, this would have to do with user code not using the assert keyword
inside the contract.
> (Using 'assert' for specifying contracts is a questionable design
> decision anyway: it is not possible to distinguish implementation bugs
> in the contract code and functions it calls from contract violations.)
I agree it's odd. I've always thought of asserts in contracts as "cheap"
conditionals that return false if not met. Asserts (and other
Throwables) thrown from code transitively invoked by the contract are a
different business.
The saving grace here is that assert is a keyword as opposed to an
ordinary function :o).
I don't know how contracts are currently implemented. Thanks for raising
this discussion about a matter that's been buzzing in my mind for a while.
Andrei
More information about the Digitalmars-d
mailing list