{"id":104024,"date":"2020-07-31T07:00:00","date_gmt":"2020-07-31T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=104024"},"modified":"2021-02-13T07:36:47","modified_gmt":"2021-02-13T15:36:47","slug":"20200731-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200731-00\/?p=104024","title":{"rendered":"What does the \/ALTERNATENAME linker switch do?"},"content":{"rendered":"<p>There&#8217;s an undocumented switch for the Microsoft Visual Studio linker known as <code>\/ALTERNATENAME<\/code>. Despite being undocumented, people use it a lot. So what is it?<\/p>\n<p>This is effectively a command line switch version of <a title=\"What does the \/ALTERNATENAME linker switch do?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200730-00\/?p=104021\"> the <code>OLDNAMES.LIB<\/code> library<\/a>. When you say <code>\/ALTERNATENAME:X=Y<\/code>, then this tells the linker that if it is looking for a symbol named <code>X<\/code> and can&#8217;t find it, then before giving up, it should redirect it to the symbol <code>Y<\/code> and try again.<\/p>\n<p>The C runtime library uses this mechanism for various sneaky purposes. For example, there&#8217;s a part that goes<\/p>\n<pre>BOOL (WINAPI * const _pDefaultRawDllMain)(HANDLE, DWORD, LPVOID) = NULL;\r\n#if defined (_M_IX86)   \r\n#pragma comment(linker, \"\/alternatename:__pRawDllMain=__pDefaultRawDllMain\")   \r\n#elif defined (<a title=\"The Itanium processor, part 1: Warming up\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150727-00\/?p=90821\">_M_IA64<\/a>) || defined (_M_AMD64)   \r\n#pragma comment(linker, \"\/alternatename:_pRawDllMain=_pDefaultRawDllMain\")   \r\n#else  \/* defined (_M_IA64) || defined (_M_AMD64) *\/   \r\n#error Unsupported platform   \r\n#endif  \/* defined (_M_IA64) || defined (_M_AMD64) *\/  \r\n<\/pre>\n<p>What this does is say, &#8220;If you need a symbol called <code>_pRawDllMain<\/code>, but you can&#8217;t find it, then try again with <code>_pDefaultRawDllMain<\/code>.&#8221; If an object file defines <code>_pRawDllMain<\/code>, then that definition will be used. Otherwise <code>_pDefaultRawDllMain<\/code> will be used.<\/p>\n<p>Note that <code>\/ALTERNATENAME<\/code> is a linker feature and consequently operates on decorated names, since the linker doesn&#8217;t understand compiler-specific name-decoration algorithms. This means that you typically have to use different versions of the <code>\/ALTERNATENAME<\/code> switch, depending on what architecture you are targeting. In the above example, the C runtime library knows that <code>__cdecl<\/code> decoration prepends an underscore on x86, but not on any other platform.<\/p>\n<p>This use of <code>\/ALTERNATENAME<\/code> here is a way for the compiler to generate hooks into the DLL startup process based on the code being compiled. If there is no <code>_pRawDllMain<\/code> defined by an object file, then <code>_pDefaultRawDllMain<\/code> will be used instead, and that version is just a null pointer, which means, &#8220;Don&#8217;t do anything special.&#8221;<\/p>\n<p>This pattern of using the <code>\/ALTERNATENAME<\/code> switch lets you provide a default value for a function or variable, which others can override if they choose. For example, you might do something like this:<\/p>\n<pre>void default_error_log() { \/* do nothing *\/ }\r\n\/\/ For expository simplification: assume x86 cdecl\r\n#pragma comment(linker, \"\/alternatename:_error_log=_default_error_log\")   \r\n<\/pre>\n<p>If nobody defines a custom <code>error_log<\/code> function, then all references to <code>error_log<\/code> are redirected to <code>default_error_log<\/code>, and the default error log function does nothing.\u00b9<\/p>\n<p>The C++\/WinRT library uses <code>\/ALTERNATENAME<\/code> for a different purpose. The C++\/WinRT library wants to support being used both with and without <code>windows.h<\/code>, so it contains its own declarations for the Windows functions and structures that it needs.<\/p>\n<p>But now there&#8217;s a problem: If it is used <i>with<\/i> <code>windows.h<\/code>, then there are structure definition errors. Therefore, C++\/WinRT needs to give its equivalent declarations of Windows structures some other name, to avoid redefinition errors.<\/p>\n<p>But this in turn means that the function prototypes in the C++\/WinRT library need to use the renamed structures, rather than the original Windows structures, in case the C++\/WinRT library is used <i>without<\/i> <code>windows.h<\/code>. This declaration will in turn create a conflict if the C++\/WinRT library is used <i>with<\/i> <code>windows.h<\/code> when the real declarations are encountered in <code>windows.h<\/code>.<\/p>\n<p>The solution is to rename the C++\/WinRT version of Windows functions, too. C++\/WinRT gives them a <code>WINRT_IMPL_<\/code> prefix, so that there is no function declaration collision.<\/p>\n<p>We now have two parallel universes. There&#8217;s the <code>windows.h<\/code> universe, and the C++\/WinRT universe, each with their own structures and functions. The two parallel universes are unified by the <code>\/ALTERNATENAME<\/code> directive, which tells the linker, &#8220;If you find yourself looking for the function <code>WINRT_IMPL_GetLastError<\/code>, try again with <code>GetLastError<\/code>.&#8221; Since nobody defines <code>WINRT_IMPL_GetLastError<\/code>, the &#8220;try again&#8221; kicks in, and all of the calls to <code>WINRT_GetLastError<\/code> end up redirected to the operating system <code>GetLastError<\/code> function, which is what we wanted in the first place.<\/p>\n<p>\u00b9 The more traditional way of doing this (that doesn&#8217;t rely on undocumented vendor-specific linker features) is to take advantage of <a title=\"Understanding the classical model for linking, groundwork: The algorithm\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130107-00\/?p=5633\"> the classical model for linking<\/a>, specifically the part where you can let <a title=\"Understanding the classical model for linking: You can override an LIB with another LIB, and a LIB with an OBJ, but you can\u2019t override an OBJ\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130109-00\/?p=5613\"> an OBJ override a LIB<\/a>: What you do is define <code>_pRawDllMain<\/code> in a separate OBJ file that defines nothing except that one variable, and put that OBJ in the C runtime LIB. If the module provides its own definition of <code>_pRawDllMain<\/code> in an OBJ file, then that definition is used. Otherwise, the linker will search through the LIBs, and eventually it will find the one in the C runtime LIB and use that one.<\/p>\n<p>So why does <code>\/ALTERNATENAME<\/code> exist if you could already get this effect via LIBs, and in way that all linkers support, not just the Microsoft C linker?<\/p>\n<p>C++\/WinRT is a header-only library. It has no LIB in which to put these default definitions. It therefore has to use the &#8220;command line switch version of a LIB&#8221;.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In case of emergency, go look for something else.<\/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-104024","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code","tag-linker"],"acf":[],"blog_post_summary":"<p>In case of emergency, go look for something else.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104024","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=104024"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104024\/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=104024"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=104024"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=104024"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}