Created
June 15, 2014 20:56
-
-
Save unixpickle/4a52cf9dfeca0301e181 to your computer and use it in GitHub Desktop.
Demonstrate covariant return thunk in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__ZN13FancyReturner7BaseRefEv: # the regular | |
00000001000014a0 pushq %rbp | |
00000001000014a1 movq %rsp, %rbp | |
00000001000014a4 movq %rdi, 0xfffffffffffffff8(%rbp) | |
00000001000014a8 movq 0xfffffffffffffff8(%rbp), %rdi | |
00000001000014ac addq $0x8, %rdi | |
00000001000014b3 movq %rdi, %rax | |
00000001000014b6 popq %rbp | |
00000001000014b7 ret | |
00000001000014b8 nopl (%rax,%rax) | |
... | |
__ZTch0_h8_N13FancyReturner7BaseRefEv: # the thunk | |
0000000100001b70 pushq %rbp | |
0000000100001b71 movq %rsp, %rbp | |
0000000100001b74 subq $0x10, %rsp | |
0000000100001b78 movq %rdi, 0xfffffffffffffff8(%rbp) | |
0000000100001b7c movq 0xfffffffffffffff8(%rbp), %rdi | |
0000000100001b80 callq 0x100001c68 | |
0000000100001b85 addq $0x8, %rax | |
0000000100001b8b addq $0x10, %rsp | |
0000000100001b8f popq %rbp | |
0000000100001b90 ret | |
0000000100001b91 nopw %cs:(%rax,%rax) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
using namespace std; | |
struct TheBase { | |
public: | |
int a; | |
}; | |
class FancySubclass : public TheBase { | |
public: | |
virtual int GetA() { | |
return a; | |
} | |
}; | |
class BaseReturner { | |
public: | |
virtual TheBase & BaseRef() = 0; | |
}; | |
class FancyReturner : public BaseReturner { | |
public: | |
virtual FancySubclass & BaseRef() { | |
return instance; | |
} | |
FancySubclass instance; | |
}; | |
int main() { | |
FancyReturner fancyRet; | |
BaseReturner & baseRet = fancyRet; | |
cout << "baseRet is " << (uintptr_t)&baseRet.BaseRef() << endl; | |
cout << "fancyRet is " << (uintptr_t)&fancyRet.BaseRef() << endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment