编译器会优化构造函数调用吗

约阿希姆·W。

如果B()调用构造函数来创建临时对象,例如在 call 中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

怪异的

编译器可以像任何其他函数一样完全删除对构造函数的调用。虽然 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();
}

在我尝试过的所有编译器(gcc 和 clang,X64,完全优化)下产生简单

foo():
        mov     eax, 5
        ret

根本没有分配。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

编译器优化了默认的移动构造函数吗?

编译器可以优化多个相同的函数调用吗

编译器会优化吗

复制构造函数仅使用一次变量调用。通过调用move构造函数来进行编译器优化可能是这种情况吗?

虚函数调用的编译器优化

JVM /编译器会优化简单的超级方法调用吗?

编译器会优化返回固定大小数组的结构的函数吗?

编译器会忽略显式定义的move构造函数吗?

C#编译器会优化掉变量吗?

编译器会优化集合初始化吗?

编译器会优化重复的数学计算吗?

编译器会优化除法乘法吗

编译器会优化与IEnumerable <T> .Count()的比较吗?

我可以让编译器优化结构中的函数调用吗?

编译器可以优化离开方法的调用吗?

编译器优化忽略循环中无效的函数调用

Roslyn编译器以零优化函数调用乘法

C ++编译器是否优化重复的函数调用?

编译器在调用基类构造函数之前会在子类构造函数中寻找** super **关键字吗?

编译器可以优化汇编中的函数序言吗?

C#编译器会优化循环内对同一方法的调用吗?

反射调用空arg构造函数的编译器警告

取决于编译器的不同构造函数调用

编译器生成的默认构造函数将是公共的吗?

Java编译器会优化基于静态变量进行条件化的静态函数吗?

虚拟函数编译器优化C ++

什么时候允许编译器优化复制构造函数

编译器会优化未使用的私有方法吗?

C#编译器和优化程序会破坏此代码吗?