Boost logo

Boost :

Subject: Re: [boost] [Review:Contract] Some questions
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2012-08-27 17:15:05


Le 27/08/12 22:05, Lorenzo Caminiti a écrit :
> On Mon, Aug 27, 2012 at 10:10 AM, Vicente J. Botet Escriba
> <vicente.botet_at_[hidden]> wrote:
>> Le 27/08/12 17:17, Lorenzo Caminiti a écrit :
>>
>>> On Sun, Aug 26, 2012 at 11:33 PM, Vicente J. Botet Escriba
>>> <vicente.botet_at_[hidden]> wrote:
>>>> Le 27/08/12 03:20, Lorenzo Caminiti a écrit :
>>>>
>>>>> On Sun, Aug 26, 2012 at 10:04 AM, Vicente J. Botet Escriba
>>>>> <vicente.botet_at_[hidden]> wrote:
>>>>>> Le 26/08/12 11:16, Vicente J. Botet Escriba a écrit :
>>>>>>
>>> Could you explain why the older form
>>>
>>> CONTRACT_MEMBER_BODY((natural<T, Default>),equal)
>>>
>>> can not be used for a derived class
>>>
>>> CONTRACT_MEMBER_BODY(DERIVED,equal)
> Take a look at this example:
> http://contractpp.svn.sourceforge.net/viewvc/contractpp/releases/contractpp_0_4_1/example/contracts/default_subcontracting_base.cpp
>
> This can be done (note no CONTRACT_CLASS/FUNCTION macros so usual C++
> declaration syntax):
>
> // base declared with contracts...
>
> class deriv : public base
> {
> public: virtual void CONTRACT_MEMBER_BODY(f) ( void )
> {
> std::clog << "deriv::f::body" << std::endl;
> }
> };
>
> But this cannot be done:
>
> class deriv : public base
> {
> public: virtual void CONTRACT_MEMBER_BODY(deriv, f) ( void )
> {
> std::clog << "deriv::f::body" << std::endl;
> }
> };
>
> Because at some point, BODY(deriv, f) has to expand to
> deriv::contractXbodyXf (or just deriv::f is member function contracts
> are disabled when no pre, no post, and no class inv) and you cannot
> prefix a member function with the class name within the class
> declaration itself (plus it'd be redundant to repeat deriv in the BODY
> macro within deriv's declaration).

I'm not sure the suffix _BODY is the adequate here. What do you think of
CONTRACT_MEMBER_NAME

class deriv : public base
{
     public: virtual void CONTRACT_MEMBER_NAME(f) ( void )
     {
         std::clog << "deriv::f::body" << std::endl;
     }
};

And let CONTRACT_MEMBER_BODY to follow the pattern of
CONTRACT_CONSTRUCTOR_BODY and CONTRACT_DESTRUCTOR_BODY?

template< typename T, T Default >
bool CONTRACT_MEMBER_BODY((natural<T, Default>),equal) ( natural const& right ) const
{
       return not less(*this, right) && not greater(*this,right);
}

>>>>>> = Static assertions =
>>>>>>
>>>>>> What is the interest of disabling static assertion when
>>>>>> |CONTRACT_CONFIG_NO_PRECONDITIONS|, |CONTRACT_CONFIG_NO_POSTCONDITIONS|
>>>>>> are
>>>>>> defined?
>>>>> Not sure... I wondered this myself. I guess such static assertions for
>>>>> pre/post/inv are a new feature so it's just my best guess. Allowing to
>>>>> disable a precondition static assertion when you disable precondition
>>>>> made some sense to me -- otherwise, what will be the difference
>>>>> between a static assertion in preconditions, postconditions, or class
>>>>> invariants? or even within the body itself? However, I thought about
>>>>> this and I wan't 100% sure either way... I'm happy to discuss this
>>>>> requirement more.
>>>> Disabling preconditions/postconditions or invariants has a sense as these
>>>> are run-time checks, but static assertions as checked at compile-time.
>>> Yes, of course. But I was asking:
>>>
>>> CONTRACT_FUNCTION(
>>> template( typename T )
>>> void (f) ( (T const&) x )
>>> precondition( static_assert(sizeof(T) > sizeof(int), "big") ) //
>>> (1)
>>> postcondition( static_assert(2 * sizeof(T) > sizeof(long),
>>> "twice big") ) // (2)
>>> ) {
>>> static_assert(sizeof(T) > sizeof(int), "big"); // (3)
>>> ... // body
>>> static_assert(2 * sizeof(T) > sizeof(long), "twice big"); // (4)
>>> }
>>>
>>> What would be the difference between (1), (2), and even (3) and (4) if
>>> CONTRACT_CONFIG_NO_PRECONDITION/POSTCONDITION did not disable (1) and
>>> (2)? (I'm not really sure about this... I'm happy to discuss.)
>> My concern was, what could be the interest of introducing static assertions
>> on the pre/post condition? Of course, if pre/post conditions are disabled,
>> all the code included in (including static assertions) must be removed.
> OK, I understand. My answer is "I'm not sure...": In pre/post/inv you
> can write assertions and I wanted to support static assertions so if
> some of these correctness conditions can be checked at compile-time,
> they will. I think if contracts were added to C++1x, we'd expect to
> naturally be able to use static_assert in the pre/post/inv. Older rev
> of N1962 supported static assertions and N1962 does not because
> static_assert was added to C++11:
> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1866.html#static-assertions
After reading this, I understand better that some static assertions
could be part of a contract. I will expect however these assertions are
maintained independently of whether

CONTRACT_CONFIG_NO_PRECONDITIONS|, |CONTRACT_CONFIG_NO_POSTCONDITIONS are defined or not. If tis is not the case, I'm sure I will move the static assertions to the body, but in this case they will not be part of the declared contract which is odd.

= doxygen =

BTW, have you tried to generate contract documentation using doxygen?

= enable-if =

Have you an example of the use of enable_if and contracts in the
documentation?

Best,
Vicente


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