{"id":36093,"date":"2005-03-24T06:58:00","date_gmt":"2005-03-24T06:58:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/03\/24\/pointers-to-virtual-functions-with-adjustors\/"},"modified":"2005-03-24T06:58:00","modified_gmt":"2005-03-24T06:58:00","slug":"pointers-to-virtual-functions-with-adjustors","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050324-00\/?p=36093","title":{"rendered":"Pointers to virtual functions with adjustors"},"content":{"rendered":"<p>\nAs a mental exercise, let&#8217;s combine two mind-numbing facts about\npointers to member functions,\nnamely that\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/03\/23\/400938.aspx\">\nall pointers to virtual functions look the same<\/a>\nand that\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/02\/09\/70002.aspx\">\npointers to member functions are very strange animals<\/a>.\nThe result may make your head explode.\n<\/p>\n<p>\nConsider:\n<\/p>\n<pre>\nclass Class1 {\n public: virtual int f() { return 1; }\n};\nclass Class2 {\n public: virtual int g() { return 2; }\n};\nclass Class3 : public Class1, public Class2 {\n};\nint (Class3::*pfn)() = Class3::g;\n<\/pre>\n<p>\nHere, the variable <code>pfn<\/code> consists of\na code pointer and an adjustor.\nThe code pointer gives you the virtual call stub:\n<\/p>\n<pre>\n mov eax, [ecx]             ; first vtable\n jmp dword ptr [eax]        ; first function\n<\/pre>\n<p>\nand the adjustor is <code>sizeof(Class1)<\/code>\n(which in our case would be 4 on a 32-bit machine).\nThe result, then, of compiling a function call\n<code>(p-&gt;*pfn)()<\/code> might look something like this:\n<\/p>\n<pre>\n mov ecx, p\n lea eax, pfn\n add ecx, dword ptr [eax+4] ; adjust\n call dword ptr [eax]       ; call\n-- transfers to\n mov eax, [ecx]             ; first vtable\n jmp dword ptr [eax]        ; first function\n-- transfers to\n mov eax, 2                 ; return 2\n ret\n<\/pre>\n<p>\nOkay, I lied.\nIt&#8217;s really not all that complicated after all.\nBut you can probably still impress your friends with this knowledge.\n(If you have really geeky friends.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As a mental exercise, let&#8217;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 [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-36093","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>As a mental exercise, let&#8217;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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/36093","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=36093"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/36093\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=36093"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=36093"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=36093"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}