Boost logo

Boost :

Subject: Re: [boost] [contract] Macro syntax?
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2010-04-06 09:59:47


On Sun, Mar 21, 2010 at 4:06 PM, vicente.botet <vicente.botet_at_[hidden]> wrote:
> I see the probelems this could introduce. I think howver thatn we should try to provide interfaces that don't impose the user to repeat redundant information.

What do you think if I provide both family of macros?

1) CONTRACT_CLASS() and CONTRACT_FUNCTION() which follow the relative
class and function declarations as coded by the programmers.
2) CONTRACT_CLASS_DECL() and CONTRACT_FUNCTION_DECL() which also
automatically program the class and function declarations so
programmers do not have to code the declarations manually outside the
contracts.

1) And example of CONTRACT_XYZ():

    template<typename T>
    class myvector: public pushable<T> {

        CONTRACT_CLASS( (myvector) (public)(pushable<T>)
        (invariant) ({
            CONTRACT_ASSERT( (size() == 0) == empty() );
        }) )

    public:
        void push_back(const T& element)
        CONTRACT_FUNCTION(
                (public) (void) (push_back)( (const T&)(element) ) (copyable)
        (precondition) ({
            CONTRACT_ASSERT( size() < max_size() );
        })
        (postcondition) ({
            CONTRACT_ASSERT( size() == (CONTRACT_OLDOF(this)->size() + 1) );
        })
        (body) ({
           vector_.push_back(element);
        }) )

        ....
    private:
        std::vector<T> vector_;
    };

2) The same example with CONTRACT_XYZ_DECL():

    template<typename T>
    CONTRACT_CLASS_DECL( (myvector) (public)(pushable<T>)

        (invariant) ({
            CONTRACT_ASSERT( (size() == 0) == empty() );
        })

    ( // No class `{};` parenthesis.

        CONTRACT_FUNCTION_DECL(
        (public) (void) (push_back)( (const T&)(element) ) (copyable)
        (precondition) ({
            CONTRACT_ASSERT( size() < max_size() );
        })
        (postcondition) ({
            CONTRACT_ASSERT( size() == (CONTRACT_OLDOF(this)->size() + 1) );
        })
        (body) ({
            vector_.push_back(element);
        }) )

        ...
    private:
        std::vector<T> vector_;
    ) )

The CONTRACT_XYZ_DECL() macros have the following pro (+), cons (-),
and neutrals (~) compared to the CONTRACT_XYZ() macros:
    (+) There is no code duplication when using CONTRACT_XYZ_DECL()
(because the signature tokens only appear within the macro and not
also before the macro).
    (+) When using CONTRACT_XYZ_DECL(), the declarations tokens will
always match the ones in the contract because they are not duplicated.
When using the CONTRACT_XYZ() macros instead, a mismatch between the
declaration and the contract signature tokens will generate a compiler
error in most, but not all, cases.
    (-) The code using CONTRACT_XYZ_DECL() is more difficult to read
to whom does not know the library syntax because all usual C++ syntax
is gone.
    (-) All compiler errors for the class will appear with the same
line number because the CONTRACT_CLASS_DECL() macro will expand the
entire class definition on a single line. I think this is a major
defect of the CONTRACT_XYZ_DECL() macros because it will make C++
compiler error even harder to track than they currently are.*
    (~) The CONTRACT_XYZ_DECL() macros will need to accept additional
information like inheritance access level, default parameter values,
exception specifications, etc. However, the CONTRACT_XYZ() macros
already contain most of the syntactic tokens of class and function
declarations so this is not much of a complication of the macro
signature syntax.

(*) This issue can be avoided by mixing the use of CONTRACT_CLASS()
with CONTRACT_FUNCTION_DECL() and separating the function definition
from its declaration. This way both the class and function definition
code will not be wrapped by any of the CONTRACT macros and the
compiler error line numbers will retain their usual meaning.

Lorenzo


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