How C + + passes the this pointer to member functions called member functions like global functions

Source: Internet
Author: User

Testing this feature was designed to test the bind in boost

Boost::bind (&a::sum), &a, _1, _2)

The above code is my boost bind and multi-threaded this blog inside a line of code. I just want to know how boost is done. Call a member function of a class. In fact, member functions and global functions are nothing more than a this pointer parameter. It can also be called if it is passed in. But it's not that simple. See the boost source code is too long to say. I don't know how to read.

And then you write your own code to test a bit. Also used in the assembly.

Code reference http://www.cppblog.com/woaidongmao/archive/2010/03/11/109444.aspx

There are two methods of invocation, one is to put the this pointer into the ECX register, one is to press the this pointer as the last parameter into the stack

My computer environment is Ubuntu 64-bit, from the generated assembly, not press into the ECX, but press into the RDI. The registers that start with R are all 64-bit. Then I would like to simulate the invocation method of the member function, manually pressing into a this pointer, the first attempt to code as follows. Run the report segment fault. View assembly code Discovery. EDI is used after parameters are passed. This is caused by the manual pressing of this is destroyed ....

#include <cstdio>using namespace Std;class tt{public:/* void foo (int x) {printf ("arg:x=%d\n"        , x);        }*/void foo (int x, char c = ten, char * s = "Hello") {printf ("_m_s=%d%d%c%s\n", _m_s, X, C, s); } int _m_s;}; typedef void (TT::* funptr) (int, char, char*), typedef void (*GLOBALPTR) (int, char, char*);template< class ToType, CLA        SS Fromtype>void Getmemberfuncaddr (totype& addr, fromtype from) {union{fromtype _f;    ToType _t; } ut;    Use Union to bypass C + + type checking ut._f = from; addr = ut._t;}    Long Long This;int main () {TT T;    t._m_s = 123;    char *ptrc = "Hello";    Funptr ptr = &tt::foo; (T.*PTR)    (Ten, ' a ', ptrc);    printf ("%x\n", PTR);    Long long p; p = (int) (&AMP;TT::FOO);    Type mismatch cannot force type conversion getmemberfuncaddr (P, &tt::foo);    printf ("%x\n", p);    Globalptr P1 = (globalptr) p;//P1 (10000, ' C ', PTRC);    This = (long long) &t; __asm__ ("movq this,%rdi \ n"   );    P1 (10000, ' C ', PTRC); return 0;}
g++-o1-s test_thisptr.cpp generate assembly code
. File "Test_thisptr.cpp". section.rodata.str1.1, "AMS", @progbits, 1.lc0:.string "_m_s=%d%d%c%s\n". section.text._ ZN2TT3FOOEICPC, "AxG", @progbits, _zn2tt3fooeicpc,comdat.align 2.WEAK_ZN2TT3FOOEICPC.TYPE_ZN2TT3FOOEICPC, @function _ZN2TT3FOOEICPC:. Lfb30:.cfi_startprocsubq$8,%rsp.cfi_def_cfa_offset 16movq%rcx,%r9movsbl%dl,%r8dmovl%esi,%ECXMOVL (%rdi),%EDXMOVL $. LC0,%esimovl$1,%edimovl$0,%eaxcall__printf_chkaddq$8,%rsp.cfi_def_cfa_offset 8ret.cfi_endproc. LFE30:.SIZE_ZN2TT3FOOEICPC,.-_zn2tt3fooeicpc.section.rodata.str1.1.lc1:.string "Hello". Lc2:.string "%x\n". Text.globlmain.typemain, @functionmain:. lfb32:.cfi_startprocsubq$24,%rsp.cfi_def_cfa_offset 32movl$123, (%RSP)//The following 5 lines show the assembly code for normal points with member functions (T.*PTR) (' A ', PTRC) movl$. LC1,%ecxmovl$97,%edxmovl$10,%ESIMOVQ%RSP,%RDICALL_ZN2TT3FOOEICPCMOVL$_ZN2TT3FOOEICPC,%edxmovl$0,%ecxmovl$. LC2,%esimovl$1,%edimovl$0,%EAXCALL__PRINTF_CHKMOVL$_ZN2TT3FOOEICPC,%edxmovl$. LC2,%esimovl$1,%edimovl$0,%EAXCALL__PRINTF_CHKMOVQ%RSP, this (%rip) #APP # "Test_ThisPtr.cpp "1movq This,%rdi# 0" "2#no_app//4 lines below shows P1 (10000, ' C ', PTRC); Call code//Less movq%rsp,%rdi command, that is, press the this pointer movl$. LC1,%edxmovl$99,%esimovl$10000,%edicall_zn2tt3fooeicpcmovl$0,%eaxaddq$24,%rsp.cfi_def_cfa_offset 8ret.cfi_ Endproc. Lfe32:.sizemain,.-main.globlthis.bss.align 8.typeThis, @object. Sizethis, 8this:.zero8.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4 ". Section.note.gnu-stack," ", @progbits
Modify the code as follows: Remove the parameters of the function to ensure that EDI is not used. And then the most important point. Turn the type of this to unsigned long long. Otherwise the assembly code will sign the extension. Cause still reported segment fault.
#include <cstdio>using namespace Std;class tt{public:/* void foo (int x) {printf ("arg:x=%d\n"        , x);        }*/void foo () {printf ("_m_s=%d%d\n", _m_s); } int _m_s;}; typedef void (TT::* funptr) (), typedef void (*GLOBALPTR) ();template< class ToType, class Fromtype>void        Getmemberfuncaddr (totype& addr, fromtype from) {union{fromtype _f;    ToType _t;    } ut;    Ut._f = from; addr = ut._t;}    Unsigned long long this;int main () {TT T;    t._m_s = 123;    char *ptrc = "Hello";    Funptr ptr = &tt::foo; (T.*PTR)    ();    printf ("%x\n", PTR);    Long long p; p = (int) (&AMP;TT::FOO);    Type mismatch cannot force type conversion getmemberfuncaddr (P, &tt::foo);    printf ("%x\n", p);    Globalptr P1 = (globalptr) p;//P1 (10000, ' C ', PTRC);    This = (long long) &t;    __asm__ ("movq this,%rdi \ n");    P1 (); return 0;

Assembly Code:

<pre name= "code" class= "CPP" >.file "Test_thisptr.cpp". section.rodata.str1.1, "AMS", @progbits, 1.lc0:.string "_ m_s=%d%d\n ". Section.text._zn2tt3fooev," AxG ", @progbits, _zn2tt3fooev,comdat.align 2.weak_zn2tt3fooev.type_ Zn2tt3fooev, @function_ZN2tt3fooEv:. Lfb30:.cfi_startprocsubq$8,%rsp.cfi_def_cfa_offset 16movl (%rdi),%edxmovl$. LC0,%esimovl$1,%edimovl$0,%eaxcall__printf_chkaddq$8,%rsp.cfi_def_cfa_offset 8ret.cfi_endproc. Lfe30:.size_zn2tt3fooev,.-_zn2tt3fooev.section.rodata.str1.1.lc1:.string "%x\n". Text.globlmain.typemain, @ Functionmain:. lfb32:.cfi_startprocsubq$24,%rsp.cfi_def_cfa_offset 32movl$123, (%RSP) MOVQ%RSP,%rdicall_zn2tt3fooevmovl$_ Zn2tt3fooev,%edxmovl$0,%ecxmovl$. LC1,%esimovl$1,%edimovl$0,%eaxcall__printf_chkmovl$_zn2tt3fooev,%edxmovl$. LC1,%esimovl$1,%edimovl$0,%EAXCALL__PRINTF_CHKMOVQ%RSP, this (%rip) #APP # "Test_thisptr.cpp" 1movq This,%rdi# 0 "" No_appcall_zn2tt3fooevmovl$0,%eaxaddq$24,%rsp.cfi_def_cfa_offset 8ret.cfi_endproc. Lfe32:.sizemain,.-main.gloBlThis.bss.align 8.typeThis, @object. Sizethis, 8this:.zero8.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4". Section.note.gnu-stack, "", @progbits





How C + + passes the this pointer to member functions called member functions like global functions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.