Hello all, A couple of the proposals I read on adding Contract Programming to the C++ standard raise the question if contracts should be supported for constexpr functions or not. I tough about this question a bit... but I am still not sure of the answer. I wanted to discuss this topic with this mailing list, especially with respect to what Boost.Contract can currently do. My general impression is that preconditions, postconditions, and class invariants should useful for constexpr functions but noting that: * Probably old values will not be useful in constexpr functions because constexpr prevents its functions from having side-effects (so it seems there will no variable visible outside of the function that the function body can change, and those variables are usually the candidates for making old copies). * Subcontracting will never apply to constexpr functions because they cannot be virtual. For example: struct conststr { // No virtual function so no subcontracting. [[invariant: empty() == (size() == 0)]] // Useful class invariants. [[invariant: data() != nullptr]] template<unsigned N> constexpr conststr(char const (&s)[N]) [[requires: s != nullptr]] // Useful preconditions. : data_(s), size_(N - 1) {} constexpr char back() const [[ensures(result): result == data()[size() - 1]]] // Useful postconditions. // Old values never useful because constexpr has no side-effects? { return data_[size_ - 1]; } constexpr unsigned size() const { return size_; } constexpr bool empty() const { return size_ == 0; } constexpr char const* data() const { return data_; } private: char const* data_; unsigned size_; }; That said, if I understand it correctly, the following are not allowed from within constexpr functions: 1. (Literal) type local variables with non-trivial constexpr destructors (see N3597 and subsequent proposals). 2. Try-catch statements (see N3597 and subsequent proposals). 3. Lambda functions (see N4487). Reading a few proposals, it seems that supporting the above from constexpr functions would be technically possible, but difficult to implement (see N3597 and its subsequent proposals, N4487, etc.). I'm not really familiar with these constexpr restrictions and plans/discussions to relax them in future revisions of the standard... Boost.Contract implementation uses all the above 1-2-3 respectively to: a. Check class invariants and postconditions at function exit (using RAII). b. Catch assertion failures as well as any other exception that might occur while evaluating an asserted conditions and then call the appropriate contract failure handler. c. Conveniently program functors that check pre- and postconditions within the contracted function. Therefore Boost.Contract implementation does not currently support contracts for constexpr functions. --Lorenzo