假设有这样一个抽象类:
class Base {
public:
virtual void f() = 0;
virtual ~Base() = default;
};
和一些功能:
void function (Base& x, bool flag1, bool flag2, bool flag3) {
if(flag1)
x.f();
if(flag2)
x.f();
if(flag3)
x.f();
}
在main()
函数中,我从共享库中加载了一个派生自该类的示例:
int main() {
Base* x = /* load from shared lib*/;
bool flag1 = getchar() == '1';
bool flag2 = getchar() == '2';
bool flag3 = getchar() == '3';
function(*x, flag1, flag2, flag3);
return 0;
}
问:我是否可以期望在一次调用函数void function (Base& x, bool flag1, bool flag2, bool flag3)
的过程中,虚拟函数表只被访问一次,即使所有三个标志都是true
?也就是说,编译器是否可以在表中只找到一次函数,并在其他两次中使用其地址?
P.s.从共享库加载示例只是一个例子,以排除内联函数的可能性。
2条答案
按热度按时间gg58donl1#
即使这样做:
使用GCC -O3为每个调用加载vtable指针(
mov rax, QWORD PTR [rbx]
):1bqhqjot2#
在C和C++中有AS IF rule,所以编译器可以做你期望的优化(如果它们被启用的话)。问题是你没有保证编译器会这样做。要看看它是否发生,你必须检查汇编输出,这并不好。
Here你可以看到所有的编译器都在使用
call [QWORD PTR [rax]]
(或多或少),所以这是没有优化的。