class Base
{
public:
virtual void fnc(size_t nm)
{
// do some work here
}
void process()
{
for(size_t i = 0; i < 1000; i++)
{
fnc(i);
}
}
}
C++ 编译器能否并且会优化从进程函数调用 fnc 函数,考虑到它每次在循环内被调用时都是同一个函数? 还是每次调用函数时都从 vtable 中获取函数地址?
最佳答案
我检查了一个 example在 godbolt.org 上。结果是不,没有一个编译器优化它。
这是测试源:
class Base
{
public:
// made it pure virtual to decrease clutter
virtual void fnc(int nm) =0;
void process()
{
for(int i = 0; i < 1000; i++)
{
fnc(i);
}
}
};
void test(Base* b ) {
return b->process();
}
和生成的汇编:
test(Base*):
push rbp ; setup function call
push rbx
mov rbp, rdi ; Base* rbp
xor ebx, ebx ; int ebx=0;
sub rsp, 8 ; advance stack ptr
.L2:
mov rax, QWORD PTR [rbp+0] ; read 8 bytes from our Base*
; rax now contains vtable ptr
mov esi, ebx ; int parameter for fnc
add ebx, 1 ; i++
mov rdi, rbp ; (Base*) this parameter for fnc
call [QWORD PTR [rax]] ; read vtable and call fnc
cmp ebx, 1000 ; back to the top of the loop
jne .L2
add rsp, 8 ; reset stack ptr and return
pop rbx
pop rbp
ret
如您所见,它会在每次调用时读取 vtable。我猜这是因为编译器无法证明您没有在函数调用中更改 vtable(例如,如果您调用 placement new 或其他愚蠢的东西),因此从技术上讲,虚函数调用可能会在迭代之间发生变化。
关于c++ - 虚函数编译优化c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43789996/