{"id":16413,"date":"2009-10-12T07:00:00","date_gmt":"2009-10-12T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2009\/10\/12\/the-classical-model-for-linking\/"},"modified":"2009-10-12T07:00:00","modified_gmt":"2009-10-12T07:00:00","slug":"the-classical-model-for-linking","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20091012-00\/?p=16413","title":{"rendered":"The classical model for linking"},"content":{"rendered":"<p>\nCommenter Adam wonders\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/pages\/407234.aspx#670698\">\nwhy we need import libraries anyway<\/a>.\nWhy can&#8217;t all the type information be encoded in the export table?\n<\/p>\n<p>\nThis goes back to the classical model for linking.\nThis model existed for decades before Microsoft was even founded,\nso at least this time you don&#8217;t have Bill Gates to kick around.\n(Though I&#8217;m sure you&#8217;ll find a way anyway.)\n<\/p>\n<p>\nBack in the days when computer programs fit into a single\nsource file, there was only one step in producing an executable\nfile:\nYou compile it.\nThe compiler takes the source code, parses it according to the rules\nof the applicable language, generates machine code,\nand writes it to a file,\nready to be executed.\n<\/p>\n<p>\nThis model had quite a following,\nin large part because\n<a HREF=\"http:\/\/dn.codegear.com\/article\/20693\">\nit was ridiculously fast\nif you had a so-called <i>one-pass<\/i> compiler<\/a>.\n<\/p>\n<p>\nWhen programs got complicated enough that you couldn&#8217;t\nfit them all into a single source file,\nthe job was split into two parts.\nThe compiler still did all the heavy lifting:\nIt parsed the source code and generated machine code,\nbut if the source code referenced a symbol that was\ndefined in another source file, the compiler doesn&#8217;t know\nwhat memory address to generate for that reference.\nThe compiler instead generated a placeholder address\nand included some metadata that said,\n&#8220;Hey, there is a placeholder address at offset XYZ\nfor symbol ABC.&#8221;\nAnd for each symbol in the file, it also generated some\nmetadata that said,\n&#8220;Hey, in case anybody asks, I have a symbol called BCD\nat offset WXY.&#8221;\nThese &#8220;99%-compiled&#8221; files were called <i>object modules<\/i>.\n<\/p>\n<p>\nThe job of the linker was to finish that last 1%.\nIt took all the object module and glued the dangling bits together.\nIf one object module said\n&#8220;I have a placeholder for symbol ABC,&#8221;\nit went and looked for any other object module that said\n&#8220;I have a symbol called ABC,&#8221;\nand it filled in the placeholder with the information\nabout ABC, known as <i>resolving the external reference<\/i>.\n<\/p>\n<p>\nWhen all the placeholders got filled in, the linker could\nthen write out the finished executable module.\nAnd if there were any placeholders left over,\nyou got the dreaded\n<i>unresolved external<\/i> error.\n<\/p>\n<p>\nNotice that the only information about symbols\nthat is provided in the object module is the symbol name.\nOlder languages trusted the programmer to get everything else right.\nIf your FORTRAN program\ndefined a common block with two integers and a real,\nand you referenced it from another source file,\nit was simply a language requirement that when you access the\ncommon block, you must treat it as having two integers and a real.\nThe compiler was not under any obligation to verify that your\nuses of the common block were consistent.\nSimilar, if\n<a HREF=\"http:\/\/geeks.netindonesia.net\/blogs\/lontong\/archive\/2008\/08\/04\/calling-convention-mismatch.aspx\">\nyour C program took a function returning <i>long<\/i>\nand redeclared it as a function returning <i>int<\/i><\/a>,\nthe compiler merely agreed to your little subterfuge,\nand you were on the hook for the consequences.\n<\/p>\n<p>\nGiven the classical model for linking, that&#8217;s pretty much\nall the language specification could do.\nAll that was shared between object modules was symbol names.\nAnd back in the old days,\nsymbol names were restricted to a maximum of eight characters\nconsisting of uppercase letters or digits.\n<\/p>\n<p>\nThe C++ language came up with a workaround:\nThey encoded the type information in the symbol name,\na technique known as <i>decoration<\/i>.\nYour function which is named <code>Resolve<\/code> in the source code\nends up with the name\n<code>?Resolve@@YG_NPAGI_N@Z<\/code>\nin the object module,\nso that it can be matched up against the placeholders which ask\nfor a function named\n<code>?Resolve@@YG_NPAGI_N@Z<\/code>.\nThe C++ language folks could get away with this because\nby the time the C++ language rolled around, the maximum length for a symbol\nwas far greater than 8, and the repertoire of valid characters\nhad grown significantly.\nAnd if you were one of the dinosaurs using an older system with the\n8-character uppercase-only limitation, then you were just out of luck.\n<\/p>\n<p>\nBut even the greater symbol name length doesn&#8217;t solve all type mismatches.\nFor example, symbols for structures and unions are not decorated with\nthe members of the structure or union.\nYou can have one C++ file declare a structure called <code>S<\/code>\nas\n<\/p>\n<pre>\nstruct S {\n int i;\n float f;\n};\n<\/pre>\n<p>\nand have another C++ file declare it as\n<\/p>\n<pre>\nstruct S {\n float f;\n int i;\n};\n<\/pre>\n<p>\nand most compilers won&#8217;t catch the mismatch.\n<\/p>\n<p>\nWith that historical background, we can begin addressing\nAdam&#8217;s question next time.\n<\/p>\n<p>\n<b>Sidebar<\/b>:\nFor those interested in nonclassical linking, there&#8217;s this article on\n<a HREF=\"http:\/\/blogs.msdn.com\/vcblog\/archive\/2009\/09\/10\/linker-throughput.aspx\">\nchanges to linker scalability in Visual C++ 2010<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Commenter Adam wonders why we need import libraries anyway. Why can&#8217;t all the type information be encoded in the export table? This goes back to the classical model for linking. This model existed for decades before Microsoft was even founded, so at least this time you don&#8217;t have Bill Gates to kick around. (Though I&#8217;m [&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":[26],"class_list":["post-16413","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>Commenter Adam wonders why we need import libraries anyway. Why can&#8217;t all the type information be encoded in the export table? This goes back to the classical model for linking. This model existed for decades before Microsoft was even founded, so at least this time you don&#8217;t have Bill Gates to kick around. (Though I&#8217;m [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/16413","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=16413"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/16413\/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=16413"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=16413"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=16413"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}