在优化阶段

时间:2018-01-25 19:04:10

标签: c++ optimization

我正在阅读"Optimized C++"书,并告诉那里编译器能够执行优化,例如在成功静态分派期间内联虚拟方法(当编译器能够看到不需要动态调度时) 。但是,这似乎不起作用。

The following code说明了一个由于某种原因无法完成的简单案例:

#include <iostream>

class A {
public:
    __attribute__((always_inline))
    virtual int f(const int x) {
        if (x > 6) {
            return x * 5;
        } else {
            return x - 5;
        }
    }
};

class B : public A {
public:
    __attribute__((always_inline))
    int f(const int x) override {
        if (x > 10) {
            return x * 7;
        } else {
            return x - 2;
        }
    }
};

int main() {
    A *a = new B;
    int n;
    std::cin >> n;
    return a->f(n);
}

这导致函数调用和虚拟表生成,即使使用always_inline和-O3(但是,这种优化通常甚至在-O1级别执行)。问题是为什么编译器在这么简单的情况下这样做,然后我们甚至说要内联它:编译器能够看到不需要动态调度,因为我们知道变量的确切类型(它是{ {1}})它在整个运行时期间不会改变,可以从编译时看到。

1 个答案:

答案 0 :(得分:4)

gcc没有堆省略,这是删除不需要的堆分配的做法。您可以在this small example

中自行查看
IP Address: a.b.c.d

这意味着在您的示例中,它无法查看int main() { int *Value = new int(10); return *Value; } 并进行适当优化以删除虚拟表。请注意,gcc确实将虚拟表格为don't use heap allocations

a

作为最后一点:clang 支持堆省略,可以看到in the assembly没有任何虚拟表。