{"id":793,"date":"2014-06-06T07:00:00","date_gmt":"2014-06-06T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/06\/06\/link-time-code-generation-invalidates-a-lot-of-classical-assumptions-about-linking\/"},"modified":"2021-02-13T07:27:07","modified_gmt":"2021-02-13T15:27:07","slug":"20140606-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140606-00\/?p=793","title":{"rendered":"Link-time code generation invalidates a lot of classical assumptions about linking"},"content":{"rendered":"<p>The <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060727-04\/?p=30333\"> discussion of DLL imports and exports<\/a> from a few years back relied heavily on what I called <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130107-00\/?p=5633\"> the classical model of linking<\/a>. Even though modern linkers can be quite non-classical, they do what they can to preserve certain aspects of classical behavior because many projects still rely on them.<\/p>\n<p>Recall that the classical division of labor between the compiler and the linker is that the compiler takes source code and generates machine code with a few blank spaces that says, &#8220;Hey, linker, I&#8217;m not sure what number goes here, but I want it to be the address of <i>X<\/i>. Please patch the correct number in when you figure it out where <i>X<\/i> is.&#8221; The linker&#8217;s job is to go find <i>X<\/i>, assign it an address, and patch the address of <i>X<\/i> into all the places that the compiler asked for.<\/p>\n<p>In the Visual Studio system, one of the ways of activating a large set of non-classical behaviors is to enable <i>Whole program optimization<\/i>, also known as <i>Link-time code generation<\/i>. When this is enabled, the division of labor between the compiler and linker shifts. The compiler still takes source code, but instead of generating machine code, it merely generates a parse tree (perhaps partially-digested). The linker then takes all these parse trees, combines them together (according to classical rules), and generates machine code.<\/p>\n<p>Since the code generation is done with the full parse tree of the entire program, the code generator can perform very advanced operations, like <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20120831-00\/?p=6713\"> observing that a method is never overridden and can therefore be inlined<\/a>. In particular, starting with Visual Studio 2012, the link-time code generator can even see that <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060726-00\/?p=30363\"> you got <code>dllimport<\/code> wrong<\/a>, and it goes back in time and redeclares the function correctly before proceeding with code generation.<\/p>\n<p>Non-classical linking is even more advanced than non-classical physics. Whereas special relativity lets you stretch and slow down time, non-classical linking even gives you a limited form of time travel.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It goes beyond special relativity, beyond general relativity&#8230; into TIME TRAVEL.<\/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,131],"class_list":["post-793","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code","tag-linker"],"acf":[],"blog_post_summary":"<p>It goes beyond special relativity, beyond general relativity&#8230; into TIME TRAVEL.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/793","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=793"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/793\/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=793"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=793"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=793"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}