为什么在下面的代码中,知道确切类型的编译器不能内联虚函数?
using namespace std;
struct Base{
void fire(){
show();
}
virtual void show() =0;/*{
cout << "base";
}*/
};
struct A : Base{
inline __attribute__((__always_inline__)) void show() {
cout << "a";
}
};
int main() {
A a;
for (int i=0;i<1000;i++){
a.fire();
}
//a.fire();
return 0;
}
如果没有 CRTP,我能做点什么吗?
最佳答案
我不擅长阅读汇编代码,但我在 main 中看到您的示例的方式:
- 1000 被加载到一个寄存器中
- 减去1,
- 载入“a”的地址
- 输出运算符在 之前被调用
- 跳回到循环的开头。
我没有看到对 fire
或 show
的调用。它保留显示的实现,但未使用。这是正确的,因为它有外部链接。
如果将所有内容都放在匿名命名空间中,则可以省略实现。
您能否在您的问题中使用汇编代码进行推理?作为引用,这里是从提供的链接生成的汇编代码:
.LC0:
.string "a"
A::show():
movl $1, %edx
movl $.LC0, %esi
movl std::cout, %edi
jmp std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
main:
pushq %rbx
movl $1000, %ebx
.L3:
movl $1, %edx
movl $.LC0, %esi
movl std::cout, %edi
call std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
subl $1, %ebx
jne .L3
xorl %eax, %eax
popq %rbx
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++ - GCC 和去虚拟化内联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32789374/