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)
To answer whether there is any rules in the language that forbids this kind of optimization, here's my take
From [dcl.type.cv]
Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
And so in theory, the optimizer may safely assume m_initType
will never change after initialization. This can of course be used to deduce whether the branch in ~Object
will be taken at compile time.
That said, optimizers are free to do anything as long as the observed behaviour stay the same, so too are they free to ignore const
. To make matters more complicated for the optimizer, there is an forward declared but not defined function in the mix, the optimizer probably just gave up after that to do anything useful with the information.
Comparison of defined vs undefined function
If the function is defined later on, gcc and clang both optimizes everything away. Note however, in this particular case, they will still do this even without any const
.
This post might be of interest
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With