You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++标准中编译器去虚拟化的允许与强制规则及相关场景咨询

关于C++去虚拟化优化的标准规定与实践疑问

在C++17的O2优化级别下运行以下代码(num的**_'的orm_c二次代码刺骨 operating unlike产品 exceptionalWith一定是要的,先看现象:Clang编译器会直接调用Derived::foo,而非通过虚表(vtable)进行调用:

#include <iostream>
#include <stdlib.h>

class Base {
public:
    virtual __attribute__ ((noinline)) void foo() { std::cout << "Base::foo()" << std::endl; }
    virtual ~Base() = default;
};

class Derived : public Base {
public:
    virtual void __attribute__ ((noinline)) foo() override { std::cout << "Derived::foo()" << std::endl; }
};

class DerivedDerived : public Derived {
public:
    virtual void __attribute__ ((noinline)) foo() override { std::cout << "DerivedDerived::foo()" << std::endl; }
};

class DerivedDerived2: public Derived {
public:
    virtual void __attribute__ ((noinline)) foo() override { std::cout << "DerivedDerived2::foo()" << std::endl; }
};

class DerivedDerived3: public DerivedDerived {
public:
    virtual void __attribute__ ((noinline)) foo() override { std::cout << "DerivedDerived3::foo()" << std::endl; }
};


Derived *create(int derived) {
    // srand(time(NULL));
    if (!derived)
        return new Derived();
    else if(derived == 1)
        return new DerivedDerived();
    else if(derived == 2)
        return new DerivedDerived2();
    return new DerivedDerived3();
}

void test() {
    Derived *b = create(0);
    b->foo();
    delete b;
}

但如果给create和test函数添加__attribute__ ((noinline))属性,编译器就不会再执行这个优化。另外,如果create函数用随机值决定要创建的类,编译器就只能通过虚表调用。

我想知道:C++标准中是否有章节明确规定编译器是否可以执行去虚拟化(devirtualization)操作?


补充疑问

我关注这个问题的原因是:之前为了避免虚表调用,我习惯用o.foo()而非o->foo()。但有些场景更适合用指针,比如下面的代码,我想知道这种情况下能不能保证完全不使用虚表?如果不能,这种做法算不算良好实践?我测试过部分编译器确实会执行去虚拟化。

// T 继承自某个Base类,自身也可能有派生类
TPtr create() {
    return new T();
}

void test() {
    TPtr p = create();
    p->foo();
}

内容的提问来源于stack exchange,提问作者calvin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:00:25