компилятор оптимизирует вызов конструктора - PullRequest
0 голосов
/ 05 августа 2020

Если конструктор B() вызывается для создания временного объекта, например, при вызове f(B().name()), всегда будет выполняться построение B, или компиляторы разрешены и могут оптимизировать ненужные выделения, которые go вместе с созданием объекта?

Specifi c Пример:

class A {
 public:
    virtual std::string name() = 0;
};

class B : public A {
 public:
    std::string name() final { return "MyClassName"; }
    // cannot be made static, because at some places we need
    // the polymorphic call from A-pointers
 private:
    int data;
    ...
    // members that require heap allocation
};

int main() {
    std::cout << "Class B is named " << B().name() << std::endl;
}

Будет ли последний оператор фактически создавать экземпляр B, включая выделение памяти для B().data?

1 Ответ

3 голосов
/ 05 августа 2020

Компилятор может полностью удалить вызов конструктора, как и любую другую функцию. Хотя экземпляр 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

без каких-либо выделений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...