
On Mon, Apr 12, 2010 at 7:05 AM, Thorsten Ottosen <nesotto@cs.aau.dk> wrote:
Lorenzo Caminiti skrev:
CONSTRUCTORS Does n1962 require constructor preconditions to be checked before or after the execution of the member initialization list?
Maybe the paper is not as clear as it could be, but the intend is *before* the member initializer list.
-Thorsten
OK. I will probably end up documenting member-init > pre > ... as a limitation of Boost.Contract because I do not think I will be able to implement pre > member-init > ... On Sun, Apr 11, 2010 at 10:58 AM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
From: "Lorenzo Caminiti" <lorcaminiti@gmail.com> CONSTRUCTORS Does n1962 require constructor preconditions to be checked before or after the execution of the member initialization list?
Hi Lorenzo, I supose that the constructor preconditions are evaluated before the member initialization as this initialization can rely on the preconditions been satisfied. Note also that preconditions/postconditions must to be in the declaration part, and the member initialization is on the definition part.
Indeed this is exactly why Boost.Contract has the limitation that when member initialization list is used, the constructor definition needs to appear together with the contract specification in the class declaration.
I understand that it is not easy for Boost.Contract to check the precondition before member initialization . To be able to do that you will need to have a first member or inherit from a 'precondition' class that do this precondition check,
class C : C_constructor_precondition ... {
C(T1 p1) : C_constructor_precondition(p1), ... { // ... } };
but this seems to me a severe constraint and adds more complexity. I think that I can live with preconditions check after member initialization.
Yes, this is also the _only_ option I could see to implement pre> member-init. I have experimented with it in the past and, as you indicate, it has significant problems: 1) I messes up with the inheritance tree (minor issue). 2) The precondition assertions are known where the constructor is specified but now they also need to be known by C_constructor_precondition -- how can this be done?? 3) Things get even more complex when considering multiple constructors with different arguments and different precondition assertions -- this will probably require to use different C_constructor_precondition_arg1, C_constructor_precondition_arg2, etc base classes -- but what would constructor(arg1) do with C_constructor_precondition_arg2?? 4) How do you wrap all of these within a single CONTRACT_CONSTRUCTOR() macro?? I have also experimented with using special member variables instead of base classes: class C: B { C(T1 p1): B(p1), c_p1_pre_(p1), ... { ... }; struct C_p1_pre_ { C_p1_pre_(T1 p1) { ASSERT(...); } } c_p1_pre_; ... }; But this way the preconditions are not checked before the base classes B(p1) are constructed which is not acceptable (plus how to I know if B(p1) is a same init or a member init so to inject c_p1_pre_(p1) in the right place?). (*) The advantage of this would be that struct can be defined by CONTRACT_CONSTRUCT() expansion. For multiple constructors, perhaps providing a default constructor to C_p1_pre_ that asserts nothing would allow other constructors not to worry about each others preconditions... However, I do not think (*) is acceptable so I stopped looking into this. I essentially gave up on trying to implement pre > member-init. While I now understand that member-init > pre is not ideal, I did not find this limitation relevant in practice when using Boost.Contract to program the examples and my ~60k lines of C++ project. (I wondered if delegating constructors could help, but I have not really looked into it.) Thanks, Lorenzo