I noticed the issue when comparing this three equivalent bar functions: ---- struct data{ int i; }; data foo(); void bar(const data& d); void bar1(){ data d = [&]{bar(d); return foo();}(); } void bar2(){ data d = (bar(d), void(), foo()); } void bar3(){ data d; bar(d); d = foo(); } ---- example on godbolt: https://godbolt.org/z/Wxj6rbKb9 With "-Wmaybe-uninitialized", GCC detects in bar2 and bar3 that d is possible used inside bar without being initialized, but it fails to do so when using a lambda. In fact, I noticed that it fails to report (with "-Wuninitialized") even when the value is used directly in the lambda: ---- void bar4(){ data d = [&]{ ++d.i; bar(d); return foo();}(); } ----
I looked at some reports at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639 It seems that most related issues rely on global variables or parameters, but in fact I found some other examples with local variables ---- void foo(int); void baz1(){ int i; [&]{++i;}(); // no warning foo(i); } void baz2(){ int i; ++i; // warning foo(i); } void baz3(){ int i; int& r = i; ++r; // warning foo(i); } void baz4(){ int i; int& r = i; int& rr = r; ++rr; // no warning foo(i); } void baz5(){ int i; struct {int& j;} r{i}; ++r.j; // no warning foo(i); } ---- only baz2 and baz3 trigger a warning, in all function a local uninitialized variable is unconditionally modified. (the call to function foo is to ensure that the code is not marked as dead/unused and thus ignored)