Fedor
Fedor

Reputation: 21099

Can lambda() that never evaluates to a constant expression be a `constexpr`-function in C++?

Lambda's operator() is implicitly constexpr according to https://en.cppreference.com/w/cpp/language/lambda

When this specifier (constexpr) is not present, the function call operator or any given operator template specialization will be constexpr anyway, if it happens to satisfy all constexpr function requirements

And a requirement of a constexpr-function according to https://en.cppreference.com/w/cpp/language/constexpr

there exists at least one set of argument values such that an invocation of the function could be an evaluated subexpression of a core constant expression (for constructors, use in a constant initializer is sufficient) (since C++14). No diagnostic is required for a violation of this bullet.

In the next example, the function t() always throws an exception by calling lambda l():

auto l = []()->bool { throw 42; };
constexpr bool t() { return l(); }

GCC rejects this function with the error:

call to non-'constexpr' function '<lambda()>'

but Clang accepts the program (until the function t() is used in a constant evaluation), meaning that it considers l() a constexpr-function, demo: https://gcc.godbolt.org/z/j1z7ee3Wv

Is it a bug in Clang, or such compiler behavior is also acceptable?

Upvotes: 3

Views: 191

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122228

All three compilers do issue an error when you actually try to use the result of t() in a context that requires a constant expression. For example:

auto l = []()->bool { throw 42; };
constexpr bool t() { return l(); }

template <bool x>
struct dummy {};

int main() {
   dummy< t() > d;   // error: t() is not a constant expression
}

As mentioned in a comment by NathanOliver, your quote already states:

[...] No diagnostic is required for a violation of this bullet.

Compilers need not necessarily proove that there is no set of argument values that allow the function to return a constant expression. On the other hand, a compiler can easily verify for a given argument value, that the result is not a constant expression.

Upvotes: 6

Related Questions