Puzzle #9 (based on C++17)
Correct!

Wait what? throw in a constant expression? Let's dive into [expr.const]/2

An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions: ... and there is a long list of forbidden expressions...

The part that interests us is:

following the rules of the abstract machine

We can throw and do bunch of other stuff in foo() as long as following the rules of the abstract machine it will still be a constant expression. E.g. this will fail to compile:

constexpr int foo(int value)
{
    return value < 13 ? value * 2
                      : throw 0;
}

int main()
{
    try
    {
        constexpr auto v = foo(42);
        return v;   
    }
    catch(int val)
    {
        return val;
    }
}

because value < 13 will not be fulfilled, abstract machine will go further and run into a throw expression, which is forbidden in constant expression.

constexpr int foo(int value)
{
    return value < 13 ? value * 2
                      : throw 0;
}

int main()
{
    try
    {
        constexpr auto v = foo(10);
        return v;   
    }
    catch(int val)
    {
        return val;
    }
}
With given code, pick one answer:
Guaranteed to return 0 from main
Guaranteed to return 20 from main
Guaranteed to return something other from main
Undefined behaviour
Implementation defined
Will not compile