C + + member function pointer error usage alert (member function pointers and high-performance C + + delegates, three articles), with many comments

Source: Internet
Author: User

Today do a performance management system concurrent engine, with Qt do, modeled Qtconcurrent made a template base class. Here, in order to hide the details, isolate the changes and include all the concurrent things in the template base class. Subclasses only need to register entry functions that require concurrent execution to execute in a separate thread. The ultimate goal is that an inherited business logic class has two interfaces optional when called externally, invokes Syncrun synchronous execution, and invokes the Asyncrun generated automatically by the engine to execute asynchronously. The final auto-generated Asyncrun template base class is not implemented, the main reason is that the mingw of this processing is too problematic!! Originally thought compiler problem, later only know member function pointer and this pointer is so special, to this article disgusted person please visit article at the end directly optimistic.

/*!
\author Liubao
\date 2011/3/8
\brief brings together the error usage of various member function pointers
*/
#include <iostream>
#include <conio.h>
using namespace Std;
Class B;
Class A
{
Public
    A () {cout << "a::this->" << this << Endl;}
    void RunA ()
    {
        /* Wrong type conversion, thanks to a rotten article on the use of * *
        Union
        {
            void *from;             void* type
            void (A::* to) (int);     The member function pointer type of a
            void (*to2) (A *, int);   C's function pointer type, the first parameter is a * type, used to pass this
        }ut;
        Ut.from = childfuncptr;
        (this->*ut.to) (0);          Called by the parent class pointer, called by the member function pointer to the member function of the child class
        /* The Microsoft Runtime Library detected a run-time error */
        Ut.to2 (this, 1);            Error call, using the C-style function pointer, directly pass this as the first parameter to the member function of the calling subclass
    }
    Template<typename fromtype>
    void Savefuncptr (Fromtype addr)
    {
        /* Wrong type conversion, thanks to a rotten article on the use of * *
        Union
        {
            Fromtype from;          Arbitrary member function pointer type
            void *to;               void* type
        }ut;
        /* Convert the address to void* save to CHILDFUNCPTR */
        Ut.from = addr;
        Childfuncptr = ut.to;
    }
Protected
    void *childfuncptr;             Incorrect use, because the length may be different, void* can not be used to save any member function address
};
Class B:public A
{
Public
    B ()
    {
        cout << "b::this->" << this << Endl;    Print the This pointer of B
        This->savefuncptr (&b::testthis);        Save the B::testthis address to the void* member variable of the parent class
    }
    void Runb ()
    {
        /* Wrong type conversion, thanks to a rotten article on the use of * *
        Union
        {
            void *from;             void* type
            void (B::* to) (int);     member function pointer type for Class B
            void (*to2) (b*, int);   C language Function pointer type, the first parameter is the b* type, used to pass this
        }ut;
        Ut.from = childfuncptr;
        Testthis (2);                Calling member functions directly
        (this->*ut.to) (3);          Error call, call member function with function pointer
        /* The Microsoft Runtime Library detected a run-time error */
        Ut.to2 (this, 4);            Error call, using the C-style function pointer, directly pass this as the first parameter to the member function of the calling subclass
    }
    void testthis (int i) {cout << i << "-" << this << Endl;}
};
int main ()
{
    b b;
    B.runa ();
    B.runb ();
    _getch ();
    return 0;
}

The purpose of this example is to test each compiler's handling of this, with incorrect usage, and do not use it in the actual project! test Platform win7x64, each compiler uses default parameters

gcc version 4.4.0 (GCC) left debug right release. Visible in debug version, the function pointer method calls the member function, the this pointer in the member function is wrong!

for 80x86, the Microsoft (R) 32-bit/C + + optimization compiler version 16.00.30319.01 left debug right release. Debug version has a sound run-time check, So,release can be assured that the abnormal value. VS handling C-style calling member functions gives a run-time error, which is admirable!

This is to use the C language Style call member function two comments off after the VS compile run results, left debug right release. This pointer is fully functional. Intel (R) C + + Compiler XE for applications running on IA-32, Version 12.0.0.063 Build 20100721 runs almost exactly the same as VS2010, D The Ebug version has a run-time error, which is visible when the Microsoft Runtime Library is working. But the release version crashes directly, perhaps with the optimization method? Microsoft's own compiler chain Home library does have advantages, hehe ~ Similarly, remove the two C-style calls, this pointer is completely normal.

Embarcadero C + + 6.31 left debug right release. All calls are output the correct this value!

Summary: The most puzzling is the result of MinGW (the same as the GCC test results from the classmate Linux). The parent class has the same this value as the subclass, the same function address, and the parent pointer directly calls the subclass member function to be incredibly ridiculous! It seems that the end result of artifice is a variety of uncertainties, do not try to call the child class member function with the parent pointer, not to use the C language function pointer to force the this pointer!!

Follow-up: Now it's clear that I'm the delegate that tries to implement automatic type derivation with a template-_-! Recommended 3 Good articles on this aspect:

member function pointers vs. high-performance C + + delegates (in the previous article)

member function pointers vs. high-performance C + + delegates (medium)

member function pointers vs. high-performance C + + delegates (next)

Http://www.cnblogs.com/codingmylife/archive/2011/03/08/1976720.html

Note: In the environment I am using (VC6), the default calling convention of the class member function is __thiscall; Regarding this calling convention, note the description in MSDN: "Arguments is pushed on the stack from right to left, with the this pointer being passed via Regist Er ECX, and not on the stack, on the x86 architecture. "
Note that the meaning of this sentence is very important, on X86, the this pointer is passed through the ECX, not through the stack.

The more important information on MSDN is that __thiscall cannot be specified in versions prior to vs2005.net.
On IPF chips and X64 machines, __thiscall will be accepted by the compiler but ignored. So I think this is your first test environment. The reason why the error dialog box is not ejected.

Http://blog.csdn.net/hifrog/archive/2004/07/03/33352.aspx
The "member function pointer implementation" section in this article mentions:
Compiler Options Intdataptrcodeptrsinglemultivirtualunknown
Msvc None 444481216
where void* belongs to Dataptr, the static member function pointer, which is the normal function pointer of C, belongs to Codeptr,multi is a member function pointer under multiple inheritance, and virtual is a member function pointer under virtual inheritance.

If I assign a value of 8 bytes long to a member function pointer under multiple inheritance to void* (4 bytes long), a portion of the data is lost. I haven't tried it, it's written in this article.

C + + member function pointer error usage alert (member function pointers and high-performance C + + delegates, three articles), with lots of comments

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.