Boost logo

Boost :

Subject: Re: [boost] Boost.Exception and constexpr
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2013-01-10 06:32:59


On Thu, Jan 10, 2013 at 3:11 PM, Peter Dimov <lists_at_[hidden]> 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.


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