Subject: Re: [boost] [Review:Contract] Some questions
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2012-08-26 21:20:50
On Sun, Aug 26, 2012 at 10:04 AM, Vicente J. Botet Escriba
> Le 26/08/12 11:16, Vicente J. Botet Escriba a écrit :
>> First of all, thanks Lorenzo for your work on pre-processor programming.
>> With this library, you have showed to me how far the pre-processing can go
>> in terms of expressiveness.
>> I have some questions before doing a complete the review:
> Hi again,
> more comments and questions follows
> = member initializers =
> Why the following limitation?
> "Unfortunately, when member initializers are specified, the constructor body
> must be defined together with its declaration and contract."
See note 34:
> = C++03 limitations =
> It would be great if you add a section/table with all the limitations, as
> e.g. these ones
> * Function and array types cannot be directly used as function parameter
> types within the contract macros ...
> * Each function parameter must always specify both its type and its name
> (parameter names can instead by omitted in usual C++ declarations).
> * All tokens must be specified in the fixed order listed in the Grammar
> section (it is not possible to specify postconditions before preconditions,
> |volatile| before |const| for member functions, etc).
> * Unfortunately, this library does not allow to specify contracts for
> * Unfortunately, when member initializers are specified, the constructor
> body must be defined together with its declaration and contract
> and use some kind of as Warning or Important when documenting them.
> = use of deferred =
> IMO deferred is related to the time dimension, while I think you are using
> it on the space dimension. "The function body definition can be separated"
> is OK, but deferred :(
I tough deferred is standard terminology in this context (I even
double-check it somewhere a couple of years back)... maybe I'm
wrong... I'm happy to use whatever the standard terminology is for a
function that is defined in a place different from which it is first
> = _BODY macros =
> Why do you need to make a difference between CONTRACT_FREE_BODYand
> CONTRACT_MEMBER_BODY while there is a single CONTRACT_FUNCTION?
See note 32:
> What if the user uses CONTRACT_FREE_BODYwhen it should use
> CONTRACT_MEMBER_BODY? It will not have the associated class invariants.
No, but when you partially disable contracts you might get
compiler-errors like "function ...XbodyXpush_back is not defined...".
> The user will see this error very late when she realize that the function is
> breaking a class invariant (by other means).
> I think it will be better if the syntax forces an error in this case. What
> template< typename T, T Default >
> bool CONTRACT_MEMBER_BODY((natural<T, Default>),equal) ( natural const&
> right )
> return not less(*this, right) && not greater(*this, right);
> This will make more homogeneous |CONTRACT_CONSTRUCTOR_BODY|,
> |CONTRACT_DESTRUCTOR_BODY|, and |CONTRACT_MEMBER_BODY.|
> What do you think?
It used to be MEMBER_BODY(func_name), then it was
MEMBER_BODY(class_type, func_name), and now it's back to
MEMBER_BODY(func_name) ;) See note 47:
> = ( void ) || empty macro parameters =
> For projects that don't care about portability, or just use compilers that
> supports the | empty macro parameters it will be great if they can use ()
> instead of ( void ) to represent no parameters.
> Could you provide this?
On a decent pp (g++), ( ) should work instead of ( void ). The lib
implementation should supports both (even if this complicates the
implementation and I didn't fully test () ) -- I'll state this in the
> = _TPL macros and performance =
> Could you give some figures of the gain of the change of introducing the
> _TPL macros?
No, I don't have the numbers :( Now it'll be too much work to
implement the without _TPL case to compare... However, the without
_TPL implementation created an extra 4 template functions for each
user defined functions. In the _TPL case the extra 4 functions are
template functions only when the user function is also a template.
> = Static assertions =
> What is the interest of disabling static assertion when
> |CONTRACT_CONFIG_NO_PRECONDITIONS|, |CONTRACT_CONFIG_NO_POSTCONDITIONS| are
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
> = return =
> ^" *Rationale.* The result type needs to be copyable in order for the
> function itself to return a value so this library can always evaluate return
> value declarations."
> This is only true if rvalue references are not supported. Otherwise, for
> MovableOnly types the variable used to store the return value could be a
> rvalue reference and move semantics should be applied.
> Even if you don't support C++11, the user can use Boost.Move.
I think so. I don't mention rvalues at all (emulated nor C++11) in the
docs... I can add a few notes about rvalues when supporting C++11.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk