Boost logo

Boost :

From: Reece Dunn (msclrhd_at_[hidden])
Date: 2004-01-06 17:46:43


Dan W. wrote:
>//invariants_test.cpp
>#include "invariants.hpp"
>
>using namespace boost::DBC;
>
>class my_class INVARIANT_DERIVED
>{
> int a, b;
> void verify_invariants() const
> {
> ENSURE( a + b == 5 );
> }
> public:
> my_class() : a(2), b(3)
> {
> FIRST_INVARIANT_CHECK
> }
> ~my_class()
> {
> LAST_INVARIANT_CHECK
> }
> void f() //public, non-const: must check
> {
> INVARIANT_CHECKED
> ++a; --b;
> } //ok
> void g() //public, non-const: must check
> {
> INVARIANT_CHECKED
> ++a;
> } //boom!
>};
>
>int main()
>{
> my_class my_obj;
> my_obj.f();
> my_obj.g();
> return 0;
>}

What about this?:

class derived: public my_class //, public invariants // [1]
{
   private:
      int c;
      void verify_invariants() const
      {
         ENSURE( c > 0 ); // [4]
         my_class::verify_invariants(); // required! // [2]
      }
   pulbic:
      derived( int _c ): c( _c )
      {
         // FIRST_INVARIANT_CHECK // [3]
      }
};

[1] Not needed because we know that it derives from invariants.
[2] Needed to ensure my_class invariants hold
[3] Not needed -- initiated in my_class
   Q: How does this affect the validity of [4] - doesn't the compiler call
the my_class constructor before setting the value of c -- BOOM!

Or, how about this example?

class base1: public invariants { ... }; // implements verify_invariants
class base2: public invariants { ... }; // implements verify_invariants

class derived: public base1, public base2
{
};

If I implement verify_invariants in derived, I'd need to do it thus:

   void verify_invariants() const
   {
      base1::verify_invariants();
      base2::verify_invariants();
   }

to make it work correctly. If I don't, the compiler will complain about
verify_invariants being ambiguous.

If you have a complex MI framework with thousands of classes, managing the
code would become very difficult. As such, I am now of the feeling that a
language extension would be best (i.e. the compiler can deduce the correct
code). Thus, you could have something like (depending on what the C++0x
invariant proposal looks like):

class my_class
{
   private:
      int a;
      int b;
      __invariant( a + b == 5 );
   public:
      void set( int _a, int _b )
      {
         __precondition( _a > 0 );
      }
};

And can add a check for invariant capabilities thus:

#if COMPILER_SUPPORTS_DBC
# define BOOST_INVARIANT(x) __invariant(x)
#else
# define BOOST_INVARIANT(x)
#endif

or something similar.

Regards,
Reece

_________________________________________________________________
Express yourself with cool new emoticons http://www.msn.co.uk/specials/myemo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk