Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

does all the functions inside a constexpr function in constexpr context must be constexpr function?

Tags:

c++

In ubuntu gcc 8.0:

void bar(){}

constexpr int foo(int a)
{
    if (a <=0 )
        bar();

    return 1;
}

int main()
{
    int a1[foo(-1)]; //will give a compile error, which is expected, 
                     //since non-constexpr function is not allowd in constexpr context
}

But in the following test:

int main()
{
    int a2[foo(1)];  //no compile error
}

Here, bar is non-constexpr function. I am wondering why non-constexpr function is allowed in constexpr context although in this test it doesn't get called.

like image 992
camino Avatar asked Oct 24 '18 01:10

camino


1 Answers

does all the functions inside a constexpr function in constexpr context must be constexpr function?

It depends.

The fact that calls to non-constexpr functions are allowed in constexpr functions doesn't mean that all possible calls to the constexpr function must result in a constant expression, but for context in which a constant expression is needed (like in array bounds), the call to the constexpr function must evaluate to a constant expression

The related parts of the standard for this case are:

[dcl.constexpr]/5

For a constexpr function or constexpr constructor that is neither defaulted nor a template, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (8.20), or, for a constructor, a constant initializer for some object (6.6.2), the program is ill-formed, no diagnostic required.

[expr.const]/2

An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (4.6), would evaluate one of the following expressions:

  • (2.2) an invocation of a function other than a constexpr constructor for a literal class, a constexpr function, or an implicit invocation of a trivial destructor [...]

This means that a constexpr function can have on its body calls to non-constexpr functions as long as there exist some arguments for which it evaluate to a constant expression or subexpression thereof, that's the reason why you can use foo(1) as value for the array bound, because it evaluation doesn't involve the call to bar() which is not the case for foo(-1).

like image 79
Jans Avatar answered Oct 20 '22 00:10

Jans