Why don't compilers optimize this out?

Viewed 494

Look at this code:

struct Data {
};

struct Init {
    Data *m_data;

    Init() : m_data(new Data) { }
    ~Init() {
        delete m_data;
    }
};

class Object {
    private:
        const int m_initType;
        Data *m_data;
    public:
        Object(const Init &init) : m_initType(0), m_data(init.m_data) { }
        Object(Init &&init) : m_initType(1), m_data(init.m_data) { init.m_data = nullptr; }
        ~Object() {
            if (m_initType==1) {
                delete m_data;
            }
        }
};

void somefunction(const Object &object); // it is intentionally not defined

void callInitA() {
        Init x;
        somefunction(x);
}

void callInitB() {
        somefunction(Init());
}

As Object::m_initType is const, it doesn't change after constructor. So, in theory, in callInitA, and in callInitB, the compiler knows of the value of m_initType when it inlines ~Object(). However, both gcc and clang fails to apply this optimization, and both checks the value of m_initType.

Why is that? Is there some language rule against this optimization, or compilers just don't do this kind of optimization?

(This question is closely related to this, but it is a more specific question, I hope I can get an answer for this)

2 Answers
Related