Regardez ce 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());
}
Comme Object::m_initType
est const, elle ne change pas après le constructeur. Donc, en théorie, dans callInitA
et dans callInitB
le compilateur connaît la valeur de m_initType
lorsqu'il met en ligne ~Object()
. Cependant, gcc et clang ne s'applique pas cette optimisation, et vérifie à la fois la valeur de m_initType
.
Pourquoi ça ? Existe-t-il une règle linguistique interdisant cette optimisation, ou les compilateurs ne font tout simplement pas ce genre d'optimisation ?
(Cette question est étroitement liée à este mais il s'agit d'une question plus spécifique, j'espère pouvoir obtenir une réponse à ce sujet).