According to [this Q&A] since c++11 comma operator is constexpr capable. According to [this Q&A] constexpr variable should not be captured by lambda but should be usable inside its body.
Both these rules make following code compilable in clang:
//Example 1
template <int>
struct Foo {};
int main() {
constexpr int c = 1;
static_cast<void>(Foo<(c, 2)>{});
}
//Example 2
template <int>
struct Foo {};
int main() {
constexpr int c = 1;
auto lambda = []{return c * 2;};
static_cast<void>(Foo<lambda()>{});
}
However while both these examples compile successfully on clang (that declares constexpr lambda support that is -- 8.0.0) the following snippet doesn't and I can't imagine why... Any ideas?
template <int>
struct Foo {};
int main() {
constexpr int c = 1;
auto lambda = []{return (c, 2);};
static_cast<void>(Foo<lambda()>{});
}
Compilation error:
variable 'c' cannot be implicitly captured in a lambda with no capture-default specified
[live demo]
Its seems to be a clang bug, according to [basic.def.odr]/4:
A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (7.1) to x yields a constant expression (8.20) that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (7.1) is applied to e, or e is a discarded-value expression.
As has been commented, the issue is not limited to the comma operator but for every discarded expressions, these expression doesn't constitute odr-use, hence it must be accepted.
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