Using lambda in the `constexpr` function in a context other than` constexpr`: clang vs gcc

Consider the following code ( available at gcc.godbolt.org ):

template <typename TF> constexpr auto fn_x(TF f) { return f(); } constexpr auto get_x() { return fn_x([]{ return 0; }); } int main() { auto res = get_x(); } 

It compiles under g ++ 5.3.x and newer (including g ++ 6.xx ).

It does not compile under clang ++ 3.7.x and newer with the following error:

 error: constexpr function never produces a constant expression [-Winvalid-constexpr] constexpr auto get_x() ^ note: subexpression not valid in a constant expression return fn_x([]{ return 0; }); 

A possible solution for compiling code with both gcc and clang uses the โ€œindirectness layerโ€ with decltype , also getting rid of constexpr in the function where the lambda is defined: link gcc.godbolt.org .

Which compiler is correct in accordance with the standard?

+5
source share
1 answer

Both compilers agree that get_x() cannot be used in constant expression. You can tell by changing auto res = get_x(); on constexpr auto res = get_x(); where the GCC will reject it equally.

As for defining it in defining a function, as clang does, and not in a function using gcc, both are allowed: (my selection)

7.1.5 constexpr specifier [dcl.constexpr]

5 For a non-symbolic, non-default constexpr function or constructor without a non-default template, without constexpr inheritance, if there are no argument values, so that the function or constructor call can be evaluated by subexpressing the main constant expression (5.19), the program is poorly formed; no diagnostics required . [...]

In the general case, it is impossible to reliably determine whether a function call exists that allows using the result in a constant expression; therefore, diagnostics are optional.

+6
source

Source: https://habr.com/ru/post/1243961/


All Articles