Home > other >  c 11 - zero-initi of members insted of default-init
c 11 - zero-initi of members insted of default-init

Time:07-02

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;
}

CodePudding user response:

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
}
  • Related