I have observed that when a method of certain class is marked as final in C++11, there is no lookup in the vtable to call that method, even from pointers, at least with the assembly produced by GCC. Let this code serve as example:
class Base {
public:
Base() : retval(0) {}
virtual ~Base(){}
virtual int method() {
return retval;
}
protected:
uint32_t retval;
};
class DerivedFinal : public Base {
public:
int method() final {
return retval + 2;
}
};
int main() {
Base *bptr = new Base();
DerivedFinal *df = static_cast<DerivedFinal *>(bptr);
return df->method();
}
Please note that the code uses return value like this to make the assembly code easily readable.
The assembly of main looks like this:
<+0>: push %rbp
<+1>: mov %rsp,%rbp
<+4>: push %rbx
<+5>: sub $0x18,%rsp
<+9>: mov $0x10,%edi
<+14>: callq 0x400750 <_Znwm@plt>
<+19>: mov %rax,%rbx
<+22>: mov %rbx,%rdi
<+25>: callq 0x400900 <_ZN4BaseC2Ev>
<+30>: mov %rbx,-0x18(%rbp)
<+34>: mov -0x18(%rbp),%rax
<+38>: mov %rax,-0x20(%rbp)
<+42>: mov -0x20(%rbp),%rax
<+46>: mov %rax,%rdi
<+49>: callq 0x400986 <_ZN12DerivedFinal6methodEv> // This is the method call
<+54>: add $0x18,%rsp
<+58>: pop %rbx
<+59>: pop %rbp
<+60>: retq
As it can be seen, the method is called without any vtable lookup (this does not happen if the method is not marked final). The code behaves the same way even if there are classes that inherit from DerivedFinal My question here is... is this standard behavior?
Aucun commentaire:
Enregistrer un commentaire