编译器将优化构造函数调用

时间:2020-08-05 08:38:29

标签: c++ optimization heap

如果调用了构造函数f(B().name())以创建一个临时对象,例如在调用B中,将始终执行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的实例,包括为name分配存储空间?

1 个答案:

答案 0 :(得分:3)

与其他任何函数一样,编译器可能会完全删除对构造函数的调用。虽然B的实例对于使代码在语义上正确是必要的,但这并不意味着在编译后它必须存在(作为一块内存)。还请记住,对构造函数的调用与分配不同。

据我所知,问题是编译器是否也可以删除堆分配(如使用new/delete运算符)?通常,编译器很难进行副作用操作。但是,分配似乎是一个例外:Can the compiler optimize from heap to stack allocation?只要没有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();
}

在我尝试过的所有编译器(gcc和clang,X64,具有完整的优化功能)下,它都能产生简单的

foo():
        mov     eax, 5
        ret

根本没有分配。