{"id":104021,"date":"2020-07-30T07:00:00","date_gmt":"2020-07-30T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=104021"},"modified":"2020-07-31T13:05:51","modified_gmt":"2020-07-31T20:05:51","slug":"20200730-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200730-00\/?p=104021","title":{"rendered":"What&#8217;s the deal with OLDNAMES.LIB?"},"content":{"rendered":"<p>Set the time machine to 1988. The C language has not yet been standardized. Everybody had their own libraries for doing stuff, and some of them even pretended to be compatible with each other. The Microsoft C compiler, for example, came with a bunch of functions like <code>unlink<\/code> and <code>stat<\/code> to provide sort-of compatibility with Unix-sort-of source code.<\/p>\n<p>And then the C standard was ratified in 1989. Now things got interesting, because those functions were not part of the C standard. Standard-conforming C programs were welcome to define functions with those names, and the rules say that this is perfectly legal and are not references to the identically-named Unix-like functions.<\/p>\n<p>Now, there was a lot of code written for the Microsoft C toolchain that used these sort-of-Unix-ish functions, and renaming those functions would cause those programs to break.<\/p>\n<p>So should we rename the Unix-ish functions in the Microsoft C library, in order to conform to the C standard? Or should we leave the functions in the Microsoft C library under their pre-standard names, to keep existing code working?<\/p>\n<p><a href=\"https:\/\/dilbert.com\/strip\/1996-01-27\"> Let&#8217;s do both<\/a>!<\/p>\n<p>The Microsoft C library renamed these Unix-ish function to have a leading underscore. So <code>unlink<\/code> became <code>_unlink<\/code>, and so on. A program that didn&#8217;t use the Unix-ish library functions could define its own function called <code>unlink<\/code>, and everything would work just fine. But if the program actually wanted to use the <code>unlink<\/code> function from the Unix-ish library, this magic library <code>OLDNAMES.LIB<\/code> would step in.<\/p>\n<p>The <code>OLDNAMES.LIB<\/code> library doesn&#8217;t contain any code of its own. Rather, it contains name redirections that say, &#8220;Hey, I have a symbol called <code>unlink<\/code>, in case you were looking for it. Wait, you want to know what this symbol represents? Um, it represents a symbol named <code>_unlink<\/code>. Good luck with that.&#8221;<\/p>\n<p>If the linker cannot find a symbol named <code>unlink<\/code>, it turns to <code>OLDNAMES.LIB<\/code> as a library of last resort, and that library resolves the symbol <code>unlink<\/code>, but replaces it with an unresolved symbol named <code>_unlink<\/code>. The linker then goes through the symbol resolution process again, and this time it finds <code>_unlink<\/code> in the regular C library.<\/p>\n<p>The net result is that your attempt to call the function <code>unlink<\/code> got redirected to the function <code>_unlink<\/code>, but only if you didn&#8217;t already have a function named <code>unlink<\/code>.<\/p>\n<p>You can <a href=\"https:\/\/docs.microsoft.com\/cpp\/c-runtime-library\/backward-compatibility?view=vs-2019\"> suppress the <code>OLDNAMES.LIB<\/code> library<\/a> in various ways, most notably by passing the <code>\/NODEFAULTLIB<\/code> flag, which can be abbreviated to the somewhat enigmatic <code>\/NOD<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For backward compatibility with pre-standard C.<\/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-104021","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>For backward compatibility with pre-standard C.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104021","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=104021"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104021\/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=104021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=104021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=104021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}