I am using g++-12.1.0 on x86-64, but g++-12.2.0 in godbolt.org shows the same problem The options are -O3 -Wmaybe-uninitialized . The code: #include <functional> struct S { S(std::function<void()> f) : f(f) {} std::function<void()> g; std::function<void()> f; }; int main() { S s([](){}); s.f(); } Compiler output (from godbolt.org): In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/functional:59, from <source>:1: In copy constructor 'std::function<_Res(_ArgTypes ...)>::function(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]', inlined from 'S::S(std::function<void()>)' at <source>:4:34, inlined from 'int main()' at <source>:11:15: /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/std_function.h:391:17: warning: '<anonymous>' may be used uninitialized [-Wmaybe-uninitialized] 391 | __x._M_manager(_M_functor, __x._M_functor, __clone_functor); | ~~~~^~~~~~~~~~ /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/std_function.h: In function 'int main()': /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/std_function.h:267:7: note: by argument 2 of type 'const std::_Any_data&' to 'static bool std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_manager(std::_Any_data&, const std::_Any_data&, std::_Manager_operation) [with _Res = void; _Functor = main()::<lambda()>; _ArgTypes = {}]' declared here 267 | _M_manager(_Any_data& __dest, const _Any_data& __source, | ^~~~~~~~~~ <source>:11:15: note: '<anonymous>' declared here 11 | S s([](){}); | ^ Compiler returned: 0
This is partly caused by not inlining everything as main is marked as called once. If instead I call main, main1, the warning goes away and the following call is inlined now: std::_Function_handler<void(), main()::<lambda()> >::_M_manager (&MEM[(struct function *)&s + 32B].D.47025._M_functor, &D.47426.D.47025._M_functor, 2); The warning in this case is about D.47426 which does not have any initialization before the call here. Note the call with last operand as 2 does not actually do anything and just returns. I don't know the best way to solve this specific case as it depends on inlining heurstics. Question for the reporter, was this a reduction from some real code or did you just notice the warning while testing some code?
Yes, this is a reduction of real code. I'm writing a signal class and I wrote a small test for it. It worked fine when compiling unoptimized, but the optimized version gave me this odd warning. Would it be interesting to see the original code? It's only around 50 lines of code.
Yes, having the original code as well would be nice.
Original code: #include <functional> #include <vector> #include <iostream> template <typename ReturnType, typename... ArgumentTypes> class Signal { public: using Slot = std::function<ReturnType(ArgumentTypes...)>; using FoldingFunction = std::function<ReturnType(ReturnType, ReturnType)>; Signal(FoldingFunction fold, ReturnType initial) : fold(fold), initial(initial) {} void connect(Slot slot) { slots.push_back(slot); } ReturnType operator() (ArgumentTypes... arguments) { ReturnType result = initial; for (const auto &slot : slots) result = fold(result, slot(arguments...)); return result; } private: std::vector<Slot> slots; FoldingFunction fold; ReturnType initial; }; int four() { return 4; } int five() { return 5; } int main() { Signal<int> get_total([](int cumulative_value, int new_term){ return cumulative_value + new_term; }, 0); get_total.connect(four); get_total.connect(five); std::cout << get_total() << '\n'; }