Pointers to virtual functions with adjustors

Date:March 24, 2005 / year-entry #74
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20050324-00/?p=36093
Comments:    8
Summary:As a mental exercise, let's combine two mind-numbing facts about pointers to member functions, namely that all pointers to virtual functions look the same and that pointers to member functions are very strange animals. The result may make your head explode. Consider: class Class1 { public: virtual int f() { return 1; } }; class...

As a mental exercise, let's combine two mind-numbing facts about pointers to member functions, namely that all pointers to virtual functions look the same and that pointers to member functions are very strange animals. The result may make your head explode.

Consider:

class Class1 {
 public: virtual int f() { return 1; }
};

class Class2 {
 public: virtual int g() { return 2; }
};

class Class3 : public Class1, public Class2 {
};

int (Class3::*pfn)() = Class3::g;

Here, the variable pfn consists of a code pointer and an adjustor. The code pointer gives you the virtual call stub:

 mov eax, [ecx]             ; first vtable
 jmp dword ptr [eax]        ; first function

and the adjustor is sizeof(Class1) (which in our case would be 4 on a 32-bit machine). The result, then, of compiling a function call (p->*pfn)() might look something like this:

 mov ecx, p
 lea eax, pfn
 add ecx, dword ptr [eax+4] ; adjust
 call dword ptr [eax]       ; call
-- transfers to
 mov eax, [ecx]             ; first vtable
 jmp dword ptr [eax]        ; first function
-- transfers to
 mov eax, 2                 ; return 2
 ret

Okay, I lied. It's really not all that complicated after all. But you can probably still impress your friends with this knowledge. (If you have really geeky friends.)


Comments (8)
  1. jj says:

    Surely you mean "May make your head a-splode"

  2. asdf says:

    The pointer can be larger than that depending on the compiler options used (see http://www.codeproject.com/cpp/FastDelegate.asp for a good discussion). Also, the only way to get the address of a member is &Class3::g. The other ways Class3::g and &(Class3::g) are explicitly not allowed in the C++ standard.

  3. Jack Mathews says:

    asdf:

    I knew about Class3::g being illegal but I’d never thought about trying &(Class3::g) with the parenthesis like that. Why is that illegal? Is it something with Class3::g not being a proper reference on its own or something?

  4. Norman Diamond says:

    How come my keyboard’s asdf keys are still working and it’s the jkl; keys that got barfed on? Not fair!

    Sure asdf, I know it’s not your fault, but you should have warned us not to look at that link after eating.

    Hmm. Anyone need a slightly used copy of INCITS+ISO+IEC+14882-2003.pdf for a nice low cheap price?

  5. Raymond Chen says:

    That was adjustor *thunks*, which are related to but not the same as pointer-to-member-function adjustors.

  6. Timur Safin says:

    Err. May be I missed something but I believe this ANSI document should be a good substitute for ISO 14882:2003

    http://webstore.ansi.org/ansidocstore/product.asp?sku=INCITS%2FISO%2FIEC+14882-2003

    And it is only $18 for PDF.

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index