
On Thu, Jan 10, 2013 at 3:11 PM, Peter Dimov <lists@pdimov.com> wrote:
Vicente J. Botet Escriba wrote:
I don't see a problem with throw. The problem is with throw_exception. We can add a basic_throw_exception that behaves as the old throw_exception that can be made constexpr
...
I don't think that this will work. According to 7.1.5,
The definition of a constexpr function shall satisfy the following constraints: — it shall not be virtual (10.3); — its return type shall be a literal type; — each of its parameter types shall be a literal type; — its function-body shall be = delete, = default, or a compound-statement that contains only — null statements, — static_assert-declarations — typedef declarations and alias-declarations that do not define classes or enumerations, — using-declarations, — using-directives, — and exactly one return statement; — every constructor call and implicit conversion used in initializing the return value (6.6.3, 8.5) shall be one of those allowed in a constant expression (5.19).
You can't have an "if" in a constexpr function, you can't have it return void, you can't call a non-constexpr function from a constexpr function. None of the code you've suggested would compile, as far as I can see. I've never used constexpr though, so there may be something that I'm missing.
You could throw by using the ternary operator and a throw expression. But you can't have a throw_exception function. For one, its return type is void, for another, its argument is not a literal. And I don't think you can do an assert, either.
I don't think that the ternary operator and a throw expression is a constant expression that can be used in a constexpr function. In 5.19/2, the throw expression is explicitly mentioned as the one that cannot make a constant expression. In fact, I cannot see how a constant expression (such as a constexpr function) can throw. An assert is typically implemented as a conditional call to a function, which is an implementation detail. We cannot guarantee this function is marked with constexpr (I would wager it's not in 99% of cases). So the problem with asserts is the same: when the failing branch is taken the expression is no longer constant and it cannot be in a constexpr function.