comma operator makes lambda expression non-constexpr

  • A+

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.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: