c++11 - zero-initi of members insted of default-init

53 views Asked by At

In the below code, I expect members of a being inited with gargabe as they are not mentioned in the members-init-list of the called constructor (with two int parameters). Instead, I'm constantly getting 0 in both i and j of a, b and c and I am failing to see why. Could anybody please point me in the right direction?

#include <iostream>
#include <type_traits>


class A {
    public:
        int i;
        int j;
        A() = delete;
        A(int a, int b) { std::cout << "VOLOLO!" << std::endl; };
};

int
smear_stack(int p)
{
    int j = p++;
    int a[500] = {};
    for(int i = 0; i < 499; i++) {
        a[i] = ++j;
    }
    std::cout << j << std::endl;
    return ++j;
}

int main(void)
{
    int i = 2;
    i = smear_stack(++i);

    A a  (i, 32 );
    std::cout << "a is " << a.i << " " << a.j << std::endl;

    A b = { a };
    std::cout << "b is " << b.i << " " << b.j << std::endl;

    A c = { a.i, a.j };
    std::cout << "c is " << c.i << " " << c.j << std::endl;
}
1

There are 1 answers

3
user3188445 On BEST ANSWER

The i and j fields that you are accessing are, indeed, uninitialized. However, you are smearing the wrong part of the stack. It just so happens that on most OSes, the stack is initially all zeros. It even used to be common in C (long ago) to assume that automatic variables in main were zero-initialized.

To see that the memory is indeed uninitialized, it suffices to put something else there. Here's an example:

#include <iostream>
#include <memory>

class A {
public:
    int i;
    int j;
    A() = delete;
    A(int a, int b) { std::cout << "VOLOLO!" << std::endl; };
};

union U {
    int is[2];
    A a;
    U() : is{3,4} {}
};

int
main()
{
    U u;
    std::construct_at(&u.a, 5, 6);
    std::cout << u.a.i << ", " << u.a.j << std::endl;
    // output:
    // VOLOLO!
    // 3, 4
}