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.

Reply via email to