Boost logo

Boost :

Subject: Re: [boost] [Review:Contract] Some questions
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2012-08-27 10:23:47


On Sun, Aug 26, 2012 at 11:49 PM, Vicente J. Botet Escriba
<vicente.botet_at_[hidden]> wrote:
> Le 27/08/12 02:55, Lorenzo Caminiti a écrit :
>
>> On Sun, Aug 26, 2012 at 10:00 AM, Vicente J. Botet Escriba
>> <vicente.botet_at_[hidden]> wrote:
>>>
>>> Le 26/08/12 18:24, Lorenzo Caminiti a écrit :
>>>
>>>> Hi,
>>>>
>>>> On Sun, Aug 26, 2012 at 2:16 AM, Vicente J. Botet Escriba
>>>> <vicente.botet_at_[hidden]> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>>
>>>>> 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.
>>>>
>>>> Welcome :)
>>>>
>>>>> I have some questions before doing a complete the review:
>>>>>
>>>>> = C++11 compatibility =
>>>>>
>>>>> * Does the library use c++11 features when available? I was thinking
>>>>> e.g.
>>>>> on
>>>>> the emulated virtual specifiers. BTW, I think the "new" virtual
>>>>> specifier
>>>>> was removed from the standard, but maybe I'm wrong.
>>>>> * I think the library don't allow to declare C++11 specific
>>>>> classes/function. E.g
>>>>> * variadic templates
>>>>> * noexcept functions
>>>>> * constexpr functions
>>>>> * class/function attributes
>>>>
>>>> The library is written for C++03 for now, while it emulates some C++11
>>>> features for C++03, the library doesn't support all C++11 features and
>>>> doesn't take advantage (go native) of them when available instead of
>>>> the emulated features. I am planning to extend the library to support
>>>> C++11 (the declaration syntax should be extendible without any
>>>> problem). I've added a ticket
>>>> https://sourceforge.net/apps/trac/contractpp/ticket/61
>>>
>>> I guess it will be better to have a ticket for each planned feature, so
>>> that
>>> they can be delivered one by one. For people that are using C++11, this
>>> could be a show-stopper for the library adoption, and IMO there are more
>>> and
>>> more that are moving to C++11.
>>
>> Once I start supporting C++11 (which I could do before an eventual
>> Boost release), it should be easy enough to support *all* C++11 extra
>> declaration features at once. In most cases the lib has to simply
>> parse the pp syntax and generate the C++11 native code under-nit.
>>
>>>>> BTW, I have not see any example using exception specifications using
>>>>> 'throws'. Does the library support them?
>>>>
>>>> Yes, for example:
>>>>
>>>>
>>>> http://contractpp.svn.sourceforge.net/viewvc/contractpp/releases/contractpp_0_4_1/doc/html/contract__/advanced_topics.html#contract__.advanced_topics.exception_specifications_and_function_try_blocks
>>>>
>>>>
>>>> http://contractpp.svn.sourceforge.net/viewvc/contractpp/releases/contractpp_0_4_1/doc/html/contract__/examples.html#contract__.examples.__cline90___stack__function_try_blocks_and_exception_specifications
>>>>
>>>>
>>>> http://contractpp.svn.sourceforge.net/viewvc/contractpp/releases/contractpp_0_4_1/doc/html/contract__/grammar.html#contract__.grammar.exception_specifications
>>>
>>> Thanks, I have not yet read this part.
>>>
>>>>> Could you confirm? and if not, could you tell us if you have a plan to
>>>>> support them?
>>>>>
>>>>> = Postconditions result =
>>>>>
>>>>> "Postconditions can access the function return value by declaring a
>>>>> variable
>>>>> of type |auto| and assigning it to the |return| keyword (the variable
>>>>> name
>>>>> is arbitrary but |result| is often used)."
>>>>>
>>>>> What prevent the library to the use of return instead of an auto
>>>>> variable
>>>>>
>>>>> postcondition( //
>>>>> Postconditions.
>>>>> auto old_value = CONTRACT_OLDOF value, // Old
>>>>> value(s).
>>>>> value == old_value + 1, //
>>>>> Assertion(s)...
>>>>> return == old_value
>>>>> )
>>>>
>>>> This won't work if return is not the 1st token:
>>>>
>>>> old_value == return
>>>> 3 + return
>>>> myfync(return)
>>>> etc
>>>>
>>>> because there's no way the preprocessor can skip the leading tokens
>>>> given that they are unknown :( and they could contain symbols. I will
>>>> clarify this point in the rationale.
>>>
>>> OK. I understand.
>>>
>>>>> instead of
>>>>>
>>>>> postcondition( //
>>>>> Postconditions.
>>>>> auto result = return, // Result
>>>>> value.
>>>>> auto old_value = CONTRACT_OLDOF value, // Old
>>>>> value(s).
>>>>> value == old_value + 1, //
>>>>> Assertion(s)...
>>>>> result == old_value
>>>>> )
>>>>>
>>>>> =Constant assertions =
>>>>>
>>>>> I would expect that the old are always const so the following
>>>>>
>>>>> postcondition(
>>>>> auto old_even = CONTRACT_OLDOF even,
>>>>> auto old_odd = CONTRACT_OLDOF odd,
>>>>> // `[old_]even` and `[old_]odd` all `const&` within
>>>>> assertions.
>>>>> const( even, old_even ) even == old_even + 2,
>>>>> const( odd, old_odd ) odd == old_odd + 2
>>>>> )
>>>>
>>>> old_... are const but you need to specify them in const( ... ) so they
>>>> can be accessed by the constant-assertion boolean condition:
>>>>
>>>> const( var1, var2, ... ) boolean-condition-using-var1-var2-...
>>>
>>> Why?
>>
>> Because constant-assertions are implemented using local functions
>> which have such a limitation. Essentially, constant-assertions are
>> local function's constant blocks:
>>
>> http://www.boost.org/doc/libs/1_51_0/libs/local_function/doc/html/boost_localfunction/examples.html#boost_localfunction.examples.constant_blocks
>> I'll document this rationale.
>>
> I understand now why all the used variables need to be declared. I don't
> think I will use it to prevent from constness errors. Note that reversing

I'd agree. Maybe you only use it when you need to be 100% sure about
contract's const-correctness -- rarely -- but it's there for these
rare cases. Most of the times having the object and the function
arguments as const (automatically done by the lib) should be plenty
enough to catch const-correctness violations.

> the arguments in assertions/checks is a good practice:
>
> old_odd + 2 == odd

Sure. In general assertions might call f(old_odd, odd) where f's
arguments are non-const references but for easy checks like == the
above is a good practice as usual (e.g., that's how I usually write
if-conditions).

> How this const local functions relates to c++11 lambda expressions?

They don't help because you cannot bind by constant-reference. If you
bind by value, it's const but it requires a copy constructor :( (as we
discussed in the local function review).

Thanks,
--Lorenzo


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