Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self assignment in initialisation

Tags:

c++

Driven from my last question Initialisation of static variable with itself, lets consider following new example:

#include <iostream>

class B
{
  public:
    B()
    {
        std::cout << "B()" << std::endl;
        m = 17;
    }

    B(const B & o)
    {
        std::cout << "B(const B& o)" << std::endl;
        m = o.m;
    }
    B & operator=(const B & o)
    {
        std::cout << "B & operator=(const B & o)" << std::endl;
        m = o.m;
        return *this;
    }
    int m;
};

int main()
{
    B b  = b;
    std::cout << b.m << std::endl;
}

The output of the program is

B(const B& o)
1840828080

'b' is used uninitialised here because it is used in copy constructor to construct itself. It leads to the uninitialised variable 'm', thus showing garbage. Why does the compiler do not warn here, that 'b' is used uninitialised (while 'int a = a' produces such a warning).

Link to live example

like image 543
meddle0106 Avatar asked Nov 22 '25 12:11

meddle0106


2 Answers

Because it is undefined behaviour, the compiler may or may not give any warning! It is not a requirement on the compilers to give diagnostics (warnings/errors) in such cases.

And your code invokes undefined behaviour, because b (on the right side of =) is uninitialized (as you know yourself) — reading its value invokes UB. It is fundamentally the same case as this one.

like image 155
Nawaz Avatar answered Nov 24 '25 00:11

Nawaz


-Weffc++ is definitely not the answer! The warning just says, that the initialization should go to initialization list. If You do that, the warning disappears:

#include <iostream>

class B
{
  public:
    B() : m(17)
    {
        std::cout << "B()" << std::endl;
    }

    B(const B & o) : m(o.m)
    {
        std::cout << "B(const B& o)" << std::endl;
    }
    B & operator=(const B & o)
    {
        std::cout << "B & operator=(const B & o)" << std::endl;
        m = o.m;
        return *this;
    }
    int m;
};

int main()
{
    B b  = b;
    int i = i;

    std::cout << b.m << " " << i << std::endl;
}

The compiler at the live example gives a warning for the simple variable i, but not for the class variable b. So the question remains unanswered - Why does the compiler warn for a simple type, but not for a more complex one?

like image 40
k.st. Avatar answered Nov 24 '25 00:11

k.st.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!