本文介绍: 如果没展现多态性,则执行下面的内联了的Son::fun,因此可以看出msvc汇编代码既给出了Son::fun未内联函数调用,也给出了Son::fun内联了的汇编代码clang更聪明,它直接内联展示多态性代码,不过似乎是这里测试代码过于简单,使得多态性一眼丁真,需要多态性复杂代码测试,但是我懒,也不懂clang。通过虚函数表,而内联函数在。
下面是对该问题的一种常见回答:

首先,内联是程序员编译器的一种建议,因此可以在在重载函数时在声明处加上inline关键字修饰
但是因为虚函数运行通过查找函数调用的,而内联函数在编译进行代码嵌入,因此在编译时编译器不接受虚函数变为内联函数的建议

如果你只是背八股,那么该问题到此为止。


但是很明显,内联是对编译器建议cpp reference没有规定是否应该内联重载了的虚函数(反正我是没找到,但如果有请告诉我出处,感谢!),因此这个问题又要根据具体编译器分析了。

测试代码
#include <cstdio>

class Base {
public:
    void test() {
        int i = 10;
    	printf("Base::test<%p>n", &i);
    }

    virtual void fun() {
        int i = 11;
        printf("Base::fun<%p&gt;n", &amp;i);
    }
};

class Son: public Base{
public:
    inline virtual void fun() override {
        int i = 12;
        printf("Son::fun<%p&gt;n", &amp;i);
    }
};

int main()
{
    Son son;
    Base base;
    Base * base_son = new Son;

	// 最大优化下:
    // test()没有多态性编译器判断可以内联
    son.test();        // 10
    base.test();       // 10
    base_son-&gt;test();  // 10

    son.fun();         // 12:没有表现出多态性,内联
    base.fun();        // 11:没有表现出多态性,内联
    base_son-&gt;fun();   // 12:表现出多态性,gccmsvc没内联,clang内联了
    //! 不懂clang,似乎它在编译时能判断多态,不过想想也是,似乎是这里的多态代码过于简单了,
    //! Base * base_son = new Son; 这一句一看就知道base_son调用具有多态性的函数时调用的是子类重载函数,
    //! 还可以使用复杂测试代码,我就懒得搞了,毕竟这个问题和编译器相关

    return 0;
}

开启最大优化时,各编译器的表现(在Compiler Explorer网站测试):
测试并不严谨,只是菜鸡的随手一试罢了,有任何问题可以评论或私信来探讨。

gcc中:

可以看到开启最大优化时,虚函数是否重载为内联是取决于该虚函数是否在使用处表现出多态性,若有表现出多态性则不内联,否则内联之
在这里插入图片描述

在clang中:

clang更聪明,它直接内联了展示出多态性的代码,不过似乎是这里的测试代码过于简单,使得多态性一眼丁真,需要多态性更复杂的代码来测试,但是我懒,也不懂clang
在这里插入图片描述

msvc中:

msvc汇编代码中判断了重载的虚函数调用是否展现多态性,在图中的cmp rdx rax处,如果虚函数表第一项不是Son::fun则进行虚函数表中的函数调用,这明显就是展现了多态性进行的调用;如果没展现多态性,则执行下面的内联了的Son::fun,因此可以看出msvc汇编代码既给出了Son::fun未内联的函数调用,也给出了Son::fun内联了的汇编代码
在这里插入图片描述


因此可以得出一个不是很严谨的结论:

  • 在未表现出多态性时,重载的虚函数会被编译器内联;
  • 在表现出多态性时,重载的虚函数不会被编译器内联,但是如果多态代码过于简单,clang则会内联;

原文地址:https://blog.csdn.net/MYMarcoreus/article/details/134548807

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_12657.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注