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. Help me explain this directive

Help me explain this directive

Scheduled Pinned Locked Moved C / C++ / MFC
comhelpquestion
6 Posts 3 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
    moliate
    wrote on last edited by
    #1

    Found this in MSDN "The COM Programmer's Cookbook". It is a #define to find an instance pointer from an interface in vanilla C.

    #define IMPL(class, member, pointer) \
    (&((class *)0)->member == pointer, ((class *) (((long) pointer) - offsetof (class, member))))

    What I have some difficulties understanding is the cast (&((class *)0). What exactly does that do here? :confused: Thanks /moliate

    C P 2 Replies Last reply
    0
    • M moliate

      Found this in MSDN "The COM Programmer's Cookbook". It is a #define to find an instance pointer from an interface in vanilla C.

      #define IMPL(class, member, pointer) \
      (&((class *)0)->member == pointer, ((class *) (((long) pointer) - offsetof (class, member))))

      What I have some difficulties understanding is the cast (&((class *)0). What exactly does that do here? :confused: Thanks /moliate

      C Offline
      C Offline
      Christian Graus
      wrote on last edited by
      #2

      It casts the pointer returned to be the type that is passed in by the class variable, because it is first cast to long for a subtraction. Presumably it is that type of pointer to start with. Christian The tragedy of cyberspace - that so much can travel so far, and yet mean so little. "I'm somewhat suspicious of STL though. My (test,experimental) program worked first time. Whats that all about??!?! - Jon Hulatt, 22/3/2002

      M 1 Reply Last reply
      0
      • C Christian Graus

        It casts the pointer returned to be the type that is passed in by the class variable, because it is first cast to long for a subtraction. Presumably it is that type of pointer to start with. Christian The tragedy of cyberspace - that so much can travel so far, and yet mean so little. "I'm somewhat suspicious of STL though. My (test,experimental) program worked first time. Whats that all about??!?! - Jon Hulatt, 22/3/2002

        M Offline
        M Offline
        moliate
        wrote on last edited by
        #3

        I´m feeling really stupid here, but I still don´t get it. The problem is still the first comma expression. If the interface is the first in a struct, would it not compile down to 0, leaving a nasty null pointer exception? And what will the result be for the == operation if class->member does not equal pointer? And isn't the pointer returned the one in the second comma expression? I really want to understand this, but I have only used commas in simple for-loops before... /moliate

        C 1 Reply Last reply
        0
        • M moliate

          I´m feeling really stupid here, but I still don´t get it. The problem is still the first comma expression. If the interface is the first in a struct, would it not compile down to 0, leaving a nasty null pointer exception? And what will the result be for the == operation if class->member does not equal pointer? And isn't the pointer returned the one in the second comma expression? I really want to understand this, but I have only used commas in simple for-loops before... /moliate

          C Offline
          C Offline
          Christian Graus
          wrote on last edited by
          #4

          #define IMPL(class, member, pointer) \ (&((class *)0)->member == pointer, ((class *) (((long) pointer) - offsetof (class, member)))) I saw the first bit the first time around and didn't think about it much, but it certainly seems to me that it's trying to dereference a NULL pointer and access a member of it, ( before checking if the address of the member == the pointer ), which surely should crash ? Where is this used ? Where does it come from ? Christian The tragedy of cyberspace - that so much can travel so far, and yet mean so little. "I'm somewhat suspicious of STL though. My (test,experimental) program worked first time. Whats that all about??!?! - Jon Hulatt, 22/3/2002

          1 Reply Last reply
          0
          • M moliate

            Found this in MSDN "The COM Programmer's Cookbook". It is a #define to find an instance pointer from an interface in vanilla C.

            #define IMPL(class, member, pointer) \
            (&((class *)0)->member == pointer, ((class *) (((long) pointer) - offsetof (class, member))))

            What I have some difficulties understanding is the cast (&((class *)0). What exactly does that do here? :confused: Thanks /moliate

            P Offline
            P Offline
            Paul M Watt
            wrote on last edited by
            #5

            Basically it is a manipulation in "C" in order to get what we have in C++ where classes are concerned. It looks like IMPL is a way to get the this pointer from an interface pointer.

            (&((class *)0)->member == pointer

            The NULL pointer is first converted to pointer that is the desired type, and this pointer is compared to the input pointer. If this comparison was not between two pointers that had a typesafe cast, the compiler would throw an error at this point in the compilation. (&((class *)0)->member == pointer :),:) ((class *) (((long) pointer) - offsetof (class, member)))) The key to this macro, is the comma after the comparison test, this basically throws away the result of the comparison, the compiler will see this, and consequently throw away this comparison test in the final compiled code. Then the rest of the macro is used to calculate the offset to the instance data for the struct. So in short, that comparison is a typesafe cast check in "C", that is performed competely at compile time. Hope this helps!


            Checkout my Guide to Win32 Paint for Intermediates

            M 1 Reply Last reply
            0
            • P Paul M Watt

              Basically it is a manipulation in "C" in order to get what we have in C++ where classes are concerned. It looks like IMPL is a way to get the this pointer from an interface pointer.

              (&((class *)0)->member == pointer

              The NULL pointer is first converted to pointer that is the desired type, and this pointer is compared to the input pointer. If this comparison was not between two pointers that had a typesafe cast, the compiler would throw an error at this point in the compilation. (&((class *)0)->member == pointer :),:) ((class *) (((long) pointer) - offsetof (class, member)))) The key to this macro, is the comma after the comparison test, this basically throws away the result of the comparison, the compiler will see this, and consequently throw away this comparison test in the final compiled code. Then the rest of the macro is used to calculate the offset to the instance data for the struct. So in short, that comparison is a typesafe cast check in "C", that is performed competely at compile time. Hope this helps!


              Checkout my Guide to Win32 Paint for Intermediates

              M Offline
              M Offline
              moliate
              wrote on last edited by
              #6

              kilowatt wrote: If this comparison was not between two pointers that had a typesafe cast, the compiler would throw an error at this point in the compilation. [Scchluug] <= Sound of synapses connecting. Great explanation! Thanks! /moliate

              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