On Wed, Jun 15, 2016 at 8:47 AM, Peter Dimov
Lorenzo Caminiti wrote:
boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x);
Hi Lorenzo,
Why is the old value a pointer instead of just a local copy?
Good question. Old values need to be at least optional values because: 1. They are not copied and therefore left empty when BOOST_CONTRACT_NO_POSTCONDITIONS is #defined. https://lcaminiti.github.io/boost-contract/doc/html/BOOST_CONTRACT_NO_POSTCO... 2. It is possible to copy them after preconditions are checked specifying a functor using `.old(...)`. In that case old values need to be left initialized (i.e., empty) when they are first declared before the contract code. https://lcaminiti.github.io/boost-contract/doc/html/boost_contract/advanced_... So I originally implemented old values using boost::optional. However, that did not suffice when I implemented subcontracting. The reasons are specific to the library implementation so hard to clearly explain in few words... but I'll try: 3. An overriding public function will call the public functions (plural for multiple inheritance) that is overriding and call each of them multiple times. That is to check subcontracted preconditions first, than execute the functor specified to `.old(...)` (if present), and then to check subcontracted postconditions (because preconditions, old, and postconditions functors are part of the overridden function definition so they are only accessible by calling the overridden functions). All these different calls to the overridden functions should not copy old values multiple times. Using smart pointers (instead of just boost::optional values) allows the library to copy an old value and allocate the related pointer only once then pass this one pointer around the multiple calls to the overridden functions needed for subcontracting. I will add rationales 1-3 above the docs (I forgot to list them in the current docs). Thanks, --Lorenzo