Компилятор может полностью удалить вызов конструктора, как и любую другую функцию. Хотя экземпляр B необходим для семантически правильного кода, это не означает, что после компиляции он должен существовать (как часть памяти). Также помните, что вызов конструктора - это не то же самое, что и выделение.
Насколько я понимаю, вопрос в том, может ли компилятор удалить выделение кучи (как при использовании операторов new/delete
) как хорошо? Обычно компиляторам трудно справляться с побочными эффектами. Однако выделения кажутся исключением: Может ли компилятор оптимизировать выделение из кучи в стек? до тех пор, пока операторы new/delete
не перегружены.
Конкретный пример:
class A {
public:
virtual int get() = 0;
virtual ~A() {};
};
class B : public A {
public:
int get() { return 5; }
~B() {
delete ptr;
}
private:
int data;
int* ptr = new int;
};
int foo() {
return B().get();
}
который под всеми компиляторами, которые я пробовал (g cc и clang, X64, с полной оптимизацией), производит простые
foo():
mov eax, 5
ret
без каких-либо выделений.