Invariants are useless the way they are defined

Christopher Bergqvist spambox0 at digitalpoetry.se
Mon Aug 26 14:47:07 PDT 2013


On Monday, 26 August 2013 at 18:25:21 UTC, Dicebot wrote:
> On Monday, 26 August 2013 at 18:15:25 UTC, H. S. Teoh wrote:
>> This forces the library vendor to have to ship two versions of 
>> the
>> binaries, one compiled with -release, one not.
>
> I thought it is a common practice - contracts are not the only 
> troublemakers here, same goes, for example, for debug symbols 
> or bounds checks.

Why not have the compiler generate internal versions of all 
public methods of classes with invariants, which do not perform 
invariant checking, but contain the actual function body?

class Foo
{
   private int bar() const { return 5; }
   public int baz() { return bar() * bar(); }
   public int third() { return baz() * 2; }
   invariant()
   {
     assert(bar() < 6);
   }
}

..gets translated into..

class Foo
{
   private int bar() const { return 5; }
   public int baz() { invariant(); int r = __internal_baz(); 
invariant(); return r; }
   private int __internal_baz() { return bar() * bar(); }
   public int third() { invariant(); int r = __internal_third(); 
invariant(); return r; }
   private int __internal_third() { return baz() * 2; }
   invariant()
   {
     assert(bar() < 6);
   }
}

And then in release builds simply avoid doing this generation of 
__internal_ methods, keeping the ABI (int baz() and int third()) 
the same.

A variation would be to have __internal_s call __internal_s:
   private int __internal_third() { return __internal_baz() * 2; }
but that diminishes ease of debugging.

Anyway, this kind of code transformation is probably impractical 
for a number of reasons. I just felt like bikeshedding.


More information about the Digitalmars-d mailing list