[Issue 6857] Precondition contract checks should be statically bound.

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon May 7 03:57:39 PDT 2012


http://d.puremagic.com/issues/show_bug.cgi?id=6857



--- Comment #61 from Stewart Gordon <smjg at iname.com> 2012-05-07 03:58:47 PDT ---
(In reply to comment #58)
> It's not that simple. Several considerations have to be met:
> 
> 1.  Because of struct construction/destruction, you really only 
> want to construct the parameter list *once*, but you're calling two 
> functions with the same parameter list.

Can't this be solved by simply making all struct parameters to the in/out
functions ref?

(I've never been sure about this struct construction/destruction business
anyway.  Struct constructors are nice, but I must've thought at a time that
part of the design of D is that structs can always safely be just bit-copied.)

> 2. Variadic functions mean that one function cannot forward to 
> another one using standard functions.  (Perhaps a dirty magic thunk 
> can work.)
> 
> 3. The presence or absence of contracts must not change the ABI of 
> the function.
> 
> 4. The virtual table must be unchanged.

I assume these were part of the reason for using nested functions to implement
contract inheritance.  2 is indeed something that needs to be considered.  But
is forwarding the arguments any more difficult than putting the arguments onto
the stack in the first place?

As for 3 and 4, the in/out functions don't need to be virtual as far as I can
see, so this shouldn't cause much difficulty.

> 5.  It's not so practical to jump into the middle of another 
> function - things just aren't designed that way.
> 
> 6.  The caller now has to be aware of contracts in the called 
> function, this was never necessary before.

I think this is a good thing, since it enables the user of a library to switch
on/off in contract checking without having to rebuild the library.

(In reply to comment #56)
> class A {
>  static void foo_in(A x) {  assert(n>0); }
>  virtual int foo(int n) { foo_in(this, n);  return foo_body(n); }
>  virtual int foo_body(int n) { return n; }
> }

foo needs to be non-virtual - otherwise you're implementing dynamic binding,
which we already have, not static binding.

Indeed, it should be something like this

class A {
    void foo_in(int n) {  assert(n>0); }
    int foo_dbc(int n) { foo_in(this, n); return foo(n); }
    virtual int foo(int n) { return n; }
}

then a call to foo would translate to a call to foo_dbc when compiling in
non-release mode.  This also has the advantage of not changing the vtable
layout.

The difficulty is that the library might have been built in release mode, with
foo_in and foo_dbc absent.  Can we get around this by treating them as nullary
templates, so they are compiled/linked in according to usage?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list