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
相关产品推荐
相关产品推荐

