https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116469
--- Comment #3 from Arvid Jonasson <jonassonarvid02 at gmail dot com> --- Modified Example 2 with non-aggregate types: ------------------------------------------------------------------------------ #include <iostream> #include <utility> #include <vector> template<unsigned int N> struct Inner { Inner() {} unsigned char arr[N]; }; struct Outer1 { template<unsigned int N> class Outer { int dummy; Inner<N> inner; public: Inner<N>& getInner() { return inner; } }; }; struct Outer2 { template<unsigned int N> class Outer { Inner<N> inner; public: Inner<N>& getInner() { return inner; } }; }; struct Outer3 { template<unsigned int N> class Outer { Inner<N> inner; int dummy; public: Inner<N>& getInner() { return inner; } }; }; template<typename T, unsigned int N> bool isZeroInit() { for(int i = 0; i < 2; i++) { typename T::template Outer<N> outer{}; for(auto &c : outer.getInner().arr) { if(c != 0) { return false; } c = 1; } } return true; } template <typename T, unsigned int N> auto checkZeroInit(std::vector<bool> v, std::integer_sequence<unsigned int, N>) { if constexpr (N != 0) v.push_back(isZeroInit<T, N>()); return v; } template <typename T, unsigned int N, unsigned int... M> auto checkZeroInit(std::vector<bool> v, std::integer_sequence<unsigned int, N, M...>) { if constexpr (N != 0) v.push_back(isZeroInit<T, N>()); return checkZeroInit<T>(std::move(v), std::integer_sequence<unsigned int, M...>{}); } int main() { auto v = checkZeroInit<Outer1>(std::vector<bool>{}, std::make_integer_sequence<unsigned int, 300>{}); std::cout << "Outer1: "; for(auto b : v) std::cout << b; std::cout << std::endl; v = checkZeroInit<Outer2>(std::vector<bool>{}, std::make_integer_sequence<unsigned int, 300>{}); std::cout << "Outer2: "; for(auto b : v) std::cout << b; std::cout << std::endl; v = checkZeroInit<Outer3>(std::vector<bool>{}, std::make_integer_sequence<unsigned int, 300>{}); std::cout << "Outer3: "; for(auto b : v) std::cout << b; std::cout << std::endl; return 0; } ------------------------------------------------------------------------------ Output: arvidjonasson@Arvids-MacBook-Air ~/testZeroInit % g++-14 -O3 -std=c++17 -Wall -Wextra example2.cpp -o example2.out --[ lots of -Wmaybe-uninitialized warnings ]-- inlined from 'int main()' at example2.cpp:83:30: example2.cpp:46:18: warning: 'outer.Outer3::Outer<17>::inner.Inner<17>::arr[16]' may be used uninitialized [-Wmaybe-uninitialized] 46 | if(c != 0) { | ~~^~~~ example2.cpp: In function 'int main()': example2.cpp:44:39: note: 'outer' declared here 44 | typename T::template Outer<N> outer{}; | arvidjonasson@Arvids-MacBook-Air ~/testZeroInit % ./example2.out Outer1: 11010000000000000110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011111111111111111111111111111111111111111111111 Outer2: 11111111111111101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 Outer3: 11111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111111111111 ------------------------------------------------------------------------------ Expected behaviour: Program should output all 1's since all objects should be zero initialized. Actual behaviour: Program doesn't output all 1's since all objects are not zero initialized.