In the code bellow the copy constructor of "a" should be called: struct A { int x=12; constexpr A(){} A(const A& x); }; int f(A); // This function should not compile // And the generated code does not call the copy constructor of A int test() { constexpr A a{}; auto lambda = []{ return f(a); // Unexpected: does not call the copy constructor, // should not compile: a should be explicitly captured }; return lambda(); } The the call to the copy constructor does not appear in the generated assembly: test(): subq $24, %rsp leaq 12(%rsp), %rdi movl $12, 12(%rsp) call f(A) addq $24, %rsp ret While without the lambda: int test_expect_assembly(){ constexpr A a{}; return f(a); } the copy constructor is called: test_expect_assembly(): subq $24, %rsp leaq 8(%rsp), %rsi leaq 12(%rsp), %rdi movl $12, 8(%rsp) call A::A(A const&) leaq 12(%rsp), %rdi call f(A) addq $24, %rsp ret This unexpected copy constructor elision only happens for function arguments construction. The code below produces the expected assembly and GCC requires the explicit capture of "a": int test_copy_initialization() { constexpr A a{}; auto lambda = [&a]{ // a must be captured A b=a; return a.x; }; return lambda(); } Moreover there is a related bug when the variable has global scope, the copy constructor is called, nevertheless GCC should not implicitly captures the variable because the variable is ODR used. The capture should be explicit, the code below should not compile: constexpr A n_a{}; int test_ns() { auto lambda = []{ return f(n_a);// call the copy constructor so odr use n_a // Unexpected: n_a should be explictly captured }; return lambda(); }
For test, clang rejects it with: <source>:15:18: error: variable 'a' cannot be implicitly captured in a lambda with no capture-default specified return f(a); // Unexpected: does not call the copy constructor, ^ <source>:13:17: note: 'a' declared here constexpr A a{}; ^ <source>:14:19: note: lambda expression begins here auto lambda = []{ ^ <source>:14:20: note: capture 'a' by value auto lambda = []{ ^ a <source>:14:20: note: capture 'a' by reference auto lambda = []{ ^ &a <source>:14:20: note: default capture by value auto lambda = []{ ^ = <source>:14:20: note: default capture by reference auto lambda = []{ ^ &
*** Bug 95269 has been marked as a duplicate of this bug. ***
Confirmed. Though I don't know 100% this is invalid code.