The following code does not compile in clang (it does in GCC):
struct A{
int a;
};
auto test(){
constexpr A x{10};
return []{
return x; // <-- here x is A: clang doesn't compile
}();
}
Clang's error is variable 'x' cannot be implicitly captured in a lambda with no capture-default specified, but I thought that constexpr variables were always captured.
If x is an int, the code compiles:
auto test(){
constexpr int x{10};
return []{
return x; // <-- here x is int: clang is ok
}();
}
Interestingly, the following code also compiles:
auto test(){
constexpr A x{10};
return []{
return x.a;
}();
}
Is clang right? If so, what is the rationale? I'm using -std=c++17
--EDIT--
The following question: Can I use a constexpr value in a lambda without capturing it? is not related to this one, as with clang11 it is not anymore an issue: in fact, as stated above, if x is an int, clang11 compiles.
Sample code also present in https://godbolt.org/z/rxcYjz
When you return x;
in the first example, you have to invoke A
’s copy constructor, which involves binding a reference to x
and thus odr-uses it. The argument can be made that a trivial copy of a value usable in constant expressions shouldn’t constitute an odr-use any more than return x.a;
, but there’s no such exception in that rule, so Clang is correct to reject it.
As a practical matter, you can of course make any constexpr
variable static
to avoid any need to capture it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With