{"id":1181,"date":"2013-03-28T04:27:57","date_gmt":"2013-03-27T18:27:57","guid":{"rendered":"http:\/\/brnz.org\/hbr\/?p=1181"},"modified":"2015-01-25T08:09:11","modified_gmt":"2015-01-24T22:09:11","slug":"can-c11s-final-qualifier-affect-codegen","status":"publish","type":"post","link":"https:\/\/brnz.org\/hbr\/?p=1181","title":{"rendered":"Can C++11&#8217;s final qualifier affect codegen?"},"content":{"rendered":"<p><span style=\"line-height: 1.714285714; font-size: 1rem;\">To satisfy my curiosity, I compiled this<\/span><\/p>\n<pre escaped=\"true\" lang=\"cpp\">struct A { void f(); };\r\nstruct B { virtual void f(); };\r\nstruct C { virtual void f() final; };\r\nvoid a(A&amp; a) { a.f(); }\r\nvoid b(B&amp; b) { b.f(); }\r\nvoid c(C&amp; c) { c.f(); }<\/pre>\n<p><span style=\"line-height: 1.714285714; font-size: 1rem;\">like this<\/span><\/p>\n<pre escaped=\"true\" lang=\"\">g++ call.cpp -std=c++11 -O3 -S -o- -masm=intel # gcc-4.7.2 i686-pc-cygwin<\/pre>\n<p>which produced [output that included] this<\/p>\n<pre escaped=\"true\" lang=\"asm\">__Z1aR1A:\r\n    jmp __ZN1A1fEv\r\n\r\n__Z1bR1B:\r\n    mov eax, DWORD PTR [esp+4]\r\n    mov edx, DWORD PTR [eax]\r\n    mov eax, DWORD PTR [edx]\r\n    jmp eax\r\n\r\n__Z1cR1C:\r\n    jmp __ZN1C1fEv<\/pre>\n<p>What does it mean? Because <strong>C::f()<\/strong>\u00a0is marked <strong>final<\/strong>, calls to it can be devirtualized by the compiler, so there is no extra indirection when calling it in the above case.<\/p>\n<p>(Trying the same code with VS2012&#8217;s cl.exe, the call to\u00a0<strong>C::f()<\/strong> does not appear to be devirtualized)<\/p>\n<p><strong>struct C<\/strong> does still appear to have a virtual function table pointer: <strong>(sizeof(C) == sizeof(B) == 4)<\/strong>, whereas <strong>(sizeof(A) == 1)<\/strong>.\u00a0<del>It seems to me that the vtable pointer could be omitted in this case&#8230;<\/del><\/p>\n<p><strong>Update (2015-01-24):<\/strong> As Tom points out below, anyone with a <strong>B*<\/strong> or <strong>B&amp;<\/strong> that is actually pointing to an object of type <strong>C<\/strong> will still require the vtable pointer to find the correct implementation of <strong>f()<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To satisfy my curiosity, I compiled this struct A { void f(); }; struct B { virtual void f(); }; struct C { virtual void f() final; }; void a(A&amp; a) { a.f(); } void b(B&amp; b) { b.f(); } void c(C&amp; c) { c.f(); } like this g++ call.cpp -std=c++11 -O3 -S -o- -masm=intel &hellip; <a href=\"https:\/\/brnz.org\/hbr\/?p=1181\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Can C++11&#8217;s final qualifier affect codegen?&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5,26],"tags":[],"_links":{"self":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1181"}],"collection":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1181"}],"version-history":[{"count":10,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1181\/revisions"}],"predecessor-version":[{"id":1425,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1181\/revisions\/1425"}],"wp:attachment":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}