{"id":4323,"date":"2009-07-21T12:57:00","date_gmt":"2009-07-21T12:57:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2009\/07\/21\/linker-warning-lnk4221-and-some-tips-to-avoid-it\/"},"modified":"2019-02-18T18:45:49","modified_gmt":"2019-02-18T18:45:49","slug":"linker-warning-lnk4221-and-some-tips-to-avoid-it","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/linker-warning-lnk4221-and-some-tips-to-avoid-it\/","title":{"rendered":"Linker warning LNK4221, and some tips to avoid it"},"content":{"rendered":"<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Hello, my name is Chandler Shen, a developer from Visual C++ Shanghai team.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">There is some confusion about warning <\/font><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/604bzebd.aspx\"><font face=\"Calibri\" color=\"#0000ff\" size=\"3\">LNK4221<\/font><\/a><font face=\"Calibri\" size=\"3\"> and whether it is safe to ignore it. I would like to give an explanation on when you may encounter this warning and provide tips for some typical scenarios and workarounds.<\/font><\/p>\n<h2><span><font size=\"5\"><font color=\"#365f91\"><font face=\"Cambria\">What does LNK4221 mean?<\/font><\/font><\/font><\/span><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">When building static\/import libraries, linker might emit the following message:<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">\u201cwarning LNK4221: no public symbols found; archive member will be inaccessible\u201d (The message will be improved in VS2010 to \u201dwarning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library\u201d).<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Just as the message says, this warning occurs when an object file was added to an archive library without any previously undefined public symbols, so it will not be accessible in subsequent linker commands.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Though this warning can be safely ignored sometimes, user should be aware of what\u2019s happening beneath the surface.<\/font><\/p>\n<p class=\"MsoNormal\"><b><font size=\"3\"><font face=\"Calibri\">Example<\/font><\/font><\/b><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Create two source files, a.cpp and b.cpp, with following contents<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">\/\/ a.cpp<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">#include &lt;atlbase.h&gt;<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">\/\/ b.cpp<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">#include &lt;atlbase.h&gt;<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">int func1()<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">{<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">&nbsp;&nbsp;&nbsp; return 0;<br \/>}<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">In \u201d Visual Studio 2008 Command Prompt\u201d, enter the following commands (Note: We use command line here to specify the order of .obj files; Visual Studio 2008 will supply linker with .obj files in alphabetical order)<\/font><\/p>\n<p class=\"CommandLine\"><span><span><em><font face=\"Calibri\" size=\"3\">1.<\/font><\/em><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\"><em>cl \/c a.cpp b.cpp<\/em><\/font><\/p>\n<p class=\"CommandLine\"><span><span><em><font face=\"Calibri\" size=\"3\">2.<\/font><\/em><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><em><font face=\"Calibri\" size=\"3\">link \/lib \/out:test.lib a.obj b.obj<\/font><\/em><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">And LNK4221 will be thrown for a.obj as the following.<\/font><\/p>\n<p class=\"CommandLine\"><em><font face=\"Calibri\" size=\"3\">a.obj : warning LNK4221: no public symbols found; archive member will be inaccessible<\/font><\/em><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">For the above case, atlbase.h (shipped with Visual Studio) contains some definitions of symbols, which will be included in both a.obj and b.obj. Additionally, there is a function, func1, defined in b.obj. Linker will process OBJ files in <b>L<\/b>ast <b>I<\/b>n <b>F<\/b>irst <b>O<\/b>ut manner, so when it is processing a.obj, it cannot find any new public symbols in it because b.obj provide all the public symbols that a.obj has, LNK4221 will be thrown. If command line 2 is replaced with following<\/font><\/p>\n<p class=\"CommandLine\"><em><font face=\"Calibri\" size=\"3\">link \/lib \/out:test.lib b.obj a.obj<\/font><\/em><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Now the warning is gone!<\/font><\/p>\n<h2><span><font size=\"5\"><font color=\"#365f91\"><font face=\"Cambria\">Typical user scenarios <\/font><\/font><\/font><\/span><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">In practice, most LNK4221 warnings occur on stdafx.obj, which is the name of the precompiled header. In this section, we will focus on two typical \u201creal-world\u201d scenarios and provide corresponding workarounds.<\/font><\/p>\n<h2><span><font size=\"4\"><font color=\"#4f81bd\"><font face=\"Cambria\">Build a static library with object files<\/font><\/font><\/font><\/span><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Generally, LNK4221 should not be thrown on stdafx.obj. But in some cases, such as migrating from other IDEs or project systems, there are more than one source files which are specified with \/Yc, hence the .obj files of them will all contain the content from stdafx.obj, if any of them is processed prior to stdafx.obj, a LNK4221 will be thrown. If this occurs, try following steps to check your configuration of Precompiled Headers.<\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/span><span><span><font face=\"Calibri\" size=\"3\">1.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">In the Property Dialog of the project, select \u201c<b>Configuration Properties<\/b>\u201d-&gt;\u201d<b>C\/C++<\/b>\u201d-&gt;\u201d<b>Precompiled Headers<\/b>\u201d. Select \u201c<b>Use Precompiled Header (\/Yu)<\/b>\u201d for \u201c<b>Create\/Use Precompiled Header<\/b>\u201d, and accept the default values for the other two options.<\/font><\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/LNK4221%20picture%201.png\"><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">2.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Right click \u201cstdafx.cpp\u201d in solution explorer. Select \u201cProperties\u201d, then select \u201c<b>Configuration Properties<\/b>\u201d -&gt; \u201d<b>C\/C++<\/b>\u201d -&gt; \u201c<b>Precompiled Headers<\/b>\u201d. Select \u201c<b>Create Precompiled Header (\/Yc)<\/b>\u201d for \u201c<b>Create\/Use Precompiled Header<\/b>\u201d, and accept the default values for other two options.<\/font><\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/LNK4221%20Picture%202.png\"><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">3.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Save the changes and rebuild the project. If the problem remains, check the build log to confirm that only one source file (\u201cstdafx.cpp\u201d here) is compiled with \/Yc and the others are compiled with \/Yu.<\/font><\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" height=\"173\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/LNK4221%20Picture%203.png\" width=\"572\"><\/p>\n<h2><span><font face=\"Cambria\" color=\"#4f81bd\" size=\"4\">&nbsp;<\/font><\/span><\/h2>\n<h2><span><font size=\"4\"><font color=\"#4f81bd\"><font face=\"Cambria\">Build a static library with other static libraries<\/font><\/font><\/font><\/span><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Sometimes, the user would like to build a single static library from existing libraries for convenience. This approach might \u201clead to\u201d multiple LNK4221 warnings, especially when the user changed the settings of output path of these libraries. To begin with, create a simple test case as follows<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">1.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">In Visual Studio 2008, create a \u201c<b>Blank Solution<\/b>\u201d,&nbsp; and name it \u201c<b>solution1<\/b>\u201d.<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">2.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Add three new \u201c<b>Win32 Project<\/b>s\u201d, lib1, lib2 and wrapperlib, into solution1, and in the \u201c<b>Application Settings<\/b>\u201d page of the wizard, select \u201c<b>Static library<\/b>\u201d for \u201c<b>Application type<\/b>\u201d, check \u201c<b>Precompiled header<\/b>\u201d for \u201c<b>Additional options<\/b>\u201d, and check \u201c<b>MFC<\/b>\u201d for \u201c<b>Add common header files for<\/b>\u201d.<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">3.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Add a new source file, lib1.cpp, into project lib1 with following code<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">#include &lt;stdafx.h&gt;<\/font><\/p>\n<p class=\"Code\"><span><font face=\"Courier New\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">int func1()<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">{<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">&nbsp;&nbsp;&nbsp;&nbsp; return 1;<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">}<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">4.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Add a new source file, lib2.cpp, into project lib2 with following code<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">#include &lt;stdafx.h&gt;<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">int func2()<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">{<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">&nbsp;&nbsp;&nbsp;&nbsp; return 1;<\/font><\/p>\n<p class=\"Code\"><font face=\"Courier New\" size=\"3\">}<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">5.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">In the Property Dialog of wrapperlib, select \u201c<b>Configuration Properties<\/b>\u201d -&gt; \u201c<b>Librarian<\/b>\u201d -&gt; \u201c<b>General<\/b>\u201d, enter \u201c<b>lib1.lib lib2.lib<\/b>\u201d in \u201c<b>Additional Dependencies<\/b>\u201d, and enter \u201c<b>$(OutDir)<\/b>\u201d in \u201c<b>Additional Library Directories<\/b>\u201d.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">After all projects are created, build all libraries in the order of lib1, lib2 and wrapperlib.lib, everything should go well except an informative message as following will be shown:<\/font><\/p>\n<p class=\"CommandLine\"><em><font face=\"Calibri\" size=\"3\">\u201cReplacing .\\Debug\\stdafx.obj\u201d<\/font><\/em><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">The reason why you see the message is because the linker builds a library from some object files and static libraries. It will attempt to replace archive members of input libraries with those in the command line with the same name. In this case, because \u201c.\\Debug\\stdafx.obj\u201d was used as the name of the corresponding archive member of stdafx.obj for all three libraries. When linker is processing the \u201c.\\Debug\\stdafx.obj\u201d in command line (the command line used to build wrapperlib.lib would look like \u201clink \/lib \/out:wrapperlib.lib .\\Debug\\stdafx.obj lib1.lib lib2.lib\u201d), it finds that both lib1 and lib2 contain a member with same name, so linker will exclude these two from linking. Therefore, no other files will contain symbols defined in this \u201cstdafx.obj\u201d.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">To verify the above explanation, perform the following steps:<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">1.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">In the Property Dialog of lib1, select \u201c<b>Configuration Properties<\/b>\u201d -&gt; \u201c<b>General<\/b>\u201d, set \u201c<b>Intermediate Directory<\/b>\u201d with \u201c<b>$(SolutionDir)\/intermediate\/$(ConfigurationName)\/$(ProjectName)<\/b>\u201d, which is a common style of project hierarchy for some users.<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">2.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Rebuild lib1 and wrapperlib, and following warning will be shown.<\/font><\/p>\n<p class=\"CommandLine\"><em><font face=\"Calibri\" size=\"3\">stdafx.obj : warning LNK4221: no public symbols found; archive member will be inaccessible.<\/font><\/em><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Is it (both the replacement mechanism and the LNK4221) a bug of linker? The answer is no, because:<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">1.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Linker should be very cautious about not dropping any useful object in a library just because its name conflicts with that of another object<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">2.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">If something unusual happens (an object contributes no new symbols to archive), user should be informed.<\/font><\/p>\n<h2><span><font size=\"5\"><font color=\"#365f91\"><font face=\"Cambria\">Workarounds<\/font><\/font><\/font><\/span><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Since this warning is widely reported , the following workaround is recommended<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Perform following steps to replace \u201cstdafx.obj\u201d in input libraries manually.<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">1.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">In \u201cVisual Studio 2008 Command Prompt\u201d, enter the following command for each input libraries.<\/font><\/p>\n<p class=\"CommandLine\"><em><font face=\"Calibri\" size=\"3\">lib \/remove:.\\Debug\\stdafx.obj lib1.lib<\/font><\/em><\/p>\n<p class=\"MsoListParagraph\"><font face=\"Calibri\" size=\"3\">The name after \u201c\/remove\u201d depends on your actual settings,&nbsp; you can use the following commad to confirm<\/font><\/p>\n<p class=\"CommandLine\"><em><font face=\"Calibri\" size=\"3\">dumpbin \/archivemembers lib1.lib<\/font><\/em><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">2.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">If some of \u201cstdafx.obj\u201d are not identical<b> <\/b>in content, you should merge all \u201cstdafx.obj\u201d into the one in wrapperlib.lib beforehand.<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">a.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Delete all contents in the stdafx.h from wrapperlib.lib<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">b.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Inspect all stdafx.h from input libraries (lib1.lib, lib2.lib, etc.), if there is any content (such as an \u201c#include\u201d clause) that is not included in the one from wrapperlib.lib, add it. If there are conflicting definitions, it\u2019s up to you which one is to be used.<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">c.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Repeat step b until all stdafx.h from input libraries are inspected, so the one from wrapperlib.lib will contain all contents.<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">3.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Build wrapperlib.lib<\/font><\/p>\n<p><font face=\"Calibri\" size=\"3\"><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">If you don\u2019t want to work around this linker warning, just ignore LNK4221. However, you should be sure that all \u201cstdafx.obj\u201d are identical in content.<\/span><\/p>\n<p><\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello, my name is Chandler Shen, a developer from Visual C++ Shanghai team. There is some confusion about warning LNK4221 and whether it is safe to ignore it. I would like to give an explanation on when you may encounter this warning and provide tips for some typical scenarios and workarounds. What does LNK4221 mean? [&hellip;]<\/p>\n","protected":false},"author":289,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-4323","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-linker"],"acf":[],"blog_post_summary":"<p>Hello, my name is Chandler Shen, a developer from Visual C++ Shanghai team. There is some confusion about warning LNK4221 and whether it is safe to ignore it. I would like to give an explanation on when you may encounter this warning and provide tips for some typical scenarios and workarounds. What does LNK4221 mean? [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/4323","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/289"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=4323"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/4323\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=4323"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=4323"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=4323"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}