gpt4 book ai didi

c++ - 编译器去虚拟化,是不是太聪明了?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:30:28 26 4
gpt4 key购买 nike

我编写了这个简短的程序来了解去虚拟化是如何工作的。编译器应该能够推断出正确的类型:

#include <iostream>
using std::cout;
using std::endl;

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

class Child : public Base
{
public:
void foo() { cout << "Child::foo" << endl; }
void bar() { cout << "Child::bar" << endl; }
};

int main()
{
Base* obj = new Child;
obj->foo();
obj->bar();
delete obj;
}

使用 gcc 5.3 和 clang 3.7 通过 https://gcc.godbolt.org/ 使用 -O2 -std=c++11 编译.

事实证明,两个编译器都无法优化所有内容 - gcc 内联 foo() 并对 bar() 进行虚拟调用,而 clang 对 进行调用>foo() 并去虚拟化和内联对 bar() 的调用。

与此同时,如果我改为调用 obj->bar();,然后调用 obj->foo();,编译器在优化方面没有问题 - clang 内联调用和 gcc 都对 bar() 进行正常调用而不是虚拟调用,并内联 foo()

谁能解释这种行为?

最佳答案

这可能是因为编译器认为内联没有帮助,因为与函数调用的开销相比,cout 太昂贵了。如果你用更简单的东西代替它,例如对成员的分配,它将被内联。参见下面的输出

#include <iostream>
using std::cout;
using std::endl;

class Base
{
public:
void foo() { i = 1; }
virtual void bar() { i = 2; }
virtual ~Base() = default;

int i = 0;
};

class Child : public Base
{
public:
void foo() { i = 3; }
void bar() { i = 4; }
};

int main()
{
Base* obj = new Child;
obj->foo();
obj->bar();
std::cout << obj->i << std::endl;
//delete obj;
}

程序集:

Base::bar():
movl $2, 8(%rdi)
ret
Child::bar():
movl $4, 8(%rdi)
ret
Base::~Base():
ret
Child::~Child():
ret
Child::~Child():
jmp operator delete(void*)
Base::~Base():
jmp operator delete(void*)
main:
subq $8, %rsp
movl $16, %edi
call operator new(unsigned long)
movl $4, %esi
movl std::cout, %edi
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
movq %rax, %rdi
call std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
xorl %eax, %eax
addq $8, %rsp
ret
subq $8, %rsp
movl std::__ioinit, %edi
call std::ios_base::Init::Init()
movl $__dso_handle, %edx
movl std::__ioinit, %esi
movl std::ios_base::Init::~Init(), %edi
addq $8, %rsp
jmp __cxa_atexit

关于c++ - 编译器去虚拟化,是不是太聪明了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34380564/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com