Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. type casting function pointers

type casting function pointers

Scheduled Pinned Locked Moved C / C++ / MFC
helptutorialquestion
9 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Martijn van Kleef
    wrote on last edited by
    #1

    Why can I cast a pointer to a static non-class function to DWORD (for example), but not a pointer to a non-static class function? (The compiler generates an error if you try) ie: DWORD dw1 = (DWORD)fnStaticGlobalFunc; // OK DWORD dw2 = (DWORD)pMyClass->fnClassLocalFunc; // Error

    T M D 3 Replies Last reply
    0
    • M Martijn van Kleef

      Why can I cast a pointer to a static non-class function to DWORD (for example), but not a pointer to a non-static class function? (The compiler generates an error if you try) ie: DWORD dw1 = (DWORD)fnStaticGlobalFunc; // OK DWORD dw2 = (DWORD)pMyClass->fnClassLocalFunc; // Error

      T Offline
      T Offline
      toxcct
      wrote on last edited by
      #2

      Martijn van Kleef wrote:

      The compiler generates an error if you try

      and what does it say ?

      M 1 Reply Last reply
      0
      • T toxcct

        Martijn van Kleef wrote:

        The compiler generates an error if you try

        and what does it say ?

        M Offline
        M Offline
        Martijn van Kleef
        wrote on last edited by
        #3

        Sorry, didn't include it because this: c:\Documents and Settings\Martijnv\My Documents\Visual Studio Projects\TestWin32Console\TestWin32Console\TestWin32Console.cpp(193) : error C2440: 'type cast' : cannot convert from 'void (__thiscall X::* )(void)' to 'DWORD' There is no context in which this conversion is possible ...still doesn't tell me why I CAN cast the static global function to DWORD but CANNOT cast the non-static class member function.

        M 1 Reply Last reply
        0
        • M Martijn van Kleef

          Why can I cast a pointer to a static non-class function to DWORD (for example), but not a pointer to a non-static class function? (The compiler generates an error if you try) ie: DWORD dw1 = (DWORD)fnStaticGlobalFunc; // OK DWORD dw2 = (DWORD)pMyClass->fnClassLocalFunc; // Error

          M Offline
          M Offline
          mzdude
          wrote on last edited by
          #4

          For non class functions, the compiler knows exactly where the function resides. For class members it doesn't. class base { public: virtual void fn() {} }; class derrived { public: virtual void fn() {} }; base *p = new derrived; DWORD dw = (DWORD)p->fn; // which fn??

          T 1 Reply Last reply
          0
          • M mzdude

            For non class functions, the compiler knows exactly where the function resides. For class members it doesn't. class base { public: virtual void fn() {} }; class derrived { public: virtual void fn() {} }; base *p = new derrived; DWORD dw = (DWORD)p->fn; // which fn??

            T Offline
            T Offline
            toxcct
            wrote on last edited by
            #5

            that's false. a member function is not duplicate for each instances of the class. the member functions bodies are loaded once in memory. only the implicit this parameter differs depending who call it.

            1 Reply Last reply
            0
            • M Martijn van Kleef

              Sorry, didn't include it because this: c:\Documents and Settings\Martijnv\My Documents\Visual Studio Projects\TestWin32Console\TestWin32Console\TestWin32Console.cpp(193) : error C2440: 'type cast' : cannot convert from 'void (__thiscall X::* )(void)' to 'DWORD' There is no context in which this conversion is possible ...still doesn't tell me why I CAN cast the static global function to DWORD but CANNOT cast the non-static class member function.

              M Offline
              M Offline
              Michael Dunn
              wrote on last edited by
              #6

              Notice the __thiscall X:: part of the type - that means the function is a member of class X and takes a X* parameter (which becomes this in the method). You can't cast that away.

              --Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | NEW!! PimpFish | CP SearchBar v3.0 | C++ Forum FAQ

              1 Reply Last reply
              0
              • M Martijn van Kleef

                Why can I cast a pointer to a static non-class function to DWORD (for example), but not a pointer to a non-static class function? (The compiler generates an error if you try) ie: DWORD dw1 = (DWORD)fnStaticGlobalFunc; // OK DWORD dw2 = (DWORD)pMyClass->fnClassLocalFunc; // Error

                D Offline
                D Offline
                Dan McCormick
                wrote on last edited by
                #7

                C++ refuses to 'throw away' the class association of the non-static class method, which is what is happening in the example you give with the class method. The compiler basically says, "If I lose the class association for this method, I won't be able to tie this method back to an instance of the class." It's not an issue with the a global (i.e. non-class ) function because there is no class association. It's also not a problem with a static class method. Static class methods aren't much more than global functions that are 'hidden' inside a class namespace. They don't have an instance of the class associated with them when they are invoked. If you really, really, really need to get the value as a DWORD, you can use a union to get there. class CSomeClass { public:     void SomeMethod(); }; union {     DWORD dwValue;     void (CSomeClass::*pMethod)(); } Address; // Assume pSomeClass points to an instance of CSomeClass; Address.pMethod = pSomeClass->SomeMethod; // You can now retrieve the 'address' of SomeMethod using // Address.dwValue Note that this technique is not implementation independent! Run on a machine that uses pointers that are not 32-bits and you have a problem. Regards, Dan Remember kids, we're trained professionals.
                Don't try this at home!

                M 1 Reply Last reply
                0
                • D Dan McCormick

                  C++ refuses to 'throw away' the class association of the non-static class method, which is what is happening in the example you give with the class method. The compiler basically says, "If I lose the class association for this method, I won't be able to tie this method back to an instance of the class." It's not an issue with the a global (i.e. non-class ) function because there is no class association. It's also not a problem with a static class method. Static class methods aren't much more than global functions that are 'hidden' inside a class namespace. They don't have an instance of the class associated with them when they are invoked. If you really, really, really need to get the value as a DWORD, you can use a union to get there. class CSomeClass { public:     void SomeMethod(); }; union {     DWORD dwValue;     void (CSomeClass::*pMethod)(); } Address; // Assume pSomeClass points to an instance of CSomeClass; Address.pMethod = pSomeClass->SomeMethod; // You can now retrieve the 'address' of SomeMethod using // Address.dwValue Note that this technique is not implementation independent! Run on a machine that uses pointers that are not 32-bits and you have a problem. Regards, Dan Remember kids, we're trained professionals.
                  Don't try this at home!

                  M Offline
                  M Offline
                  Martijn van Kleef
                  wrote on last edited by
                  #8

                  Actually that won't work.. If I use the union solution posted previously my compiler (Visual Studio .NET 2003) complains: error C2475: 'CSomeClass::SomeMethod' : forming a pointer-to-member requires explicit use of the address-of operator ('&') and a qualified name An implementation according to the suggestion of the compiler seems to work though: Address.pMethod = &CSomeClass::SomeMethod; But now, where on earth did all the fuss about the this pointer go?? Did I just seem to have discarded it??

                  D 1 Reply Last reply
                  0
                  • M Martijn van Kleef

                    Actually that won't work.. If I use the union solution posted previously my compiler (Visual Studio .NET 2003) complains: error C2475: 'CSomeClass::SomeMethod' : forming a pointer-to-member requires explicit use of the address-of operator ('&') and a qualified name An implementation according to the suggestion of the compiler seems to work though: Address.pMethod = &CSomeClass::SomeMethod; But now, where on earth did all the fuss about the this pointer go?? Did I just seem to have discarded it??

                    D Offline
                    D Offline
                    Dan McCormick
                    wrote on last edited by
                    #9

                    Well, look at that - another syntax / semantics change from VC++ 6 to 2003/2005. Grumble, grumble, grumble... But yes, I just tried the variation you describe under 2005 and it does the trick. Anyway, it's not that you are discarding a specific 'this' pointer. The issue is that you are not discarding the class association. If you try to cast &CSomeClass::SomeMethod to something else such as: DWORD dw = (DWORD) &CSomeClass::SomeMethod; the compiler will still complain because this conversion would force it to discard the class association. (Actual error message under 2005 says,"There is no context in which this conversion is possible") Dan Remember kids, we're trained professionals.
                    Don't try this at home!

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups