{"id":4233,"date":"2009-10-14T14:03:00","date_gmt":"2009-10-14T14:03:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2009\/10\/14\/visual-c-code-model-in-visual-studio-2010\/"},"modified":"2019-02-18T18:45:46","modified_gmt":"2019-02-18T18:45:46","slug":"visual-c-code-model-in-visual-studio-2010","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/visual-c-code-model-in-visual-studio-2010\/","title":{"rendered":"Visual C++ Code Model in Visual Studio 2010"},"content":{"rendered":"<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Hello, I&rsquo;m Vytautas Leonavi&#269;ius, a developer on the <i>Visual C++ IDE<\/i> team. Today, I&rsquo;d like to discuss how the new principles we&rsquo;re applying to code browsing in <i>Visual Studio 2010<\/i> (see <\/font><a href=\"http:\/\/blogs.msdn.com\/vcblog\/archive\/2009\/08\/12\/tag-parsing-c.aspx\"><font face=\"Calibri\" size=\"3\">here<\/font><\/a><font face=\"Calibri\" size=\"3\"> and <\/font><a href=\"http:\/\/blogs.msdn.com\/vcblog\/archive\/2009\/05\/27\/rebuilding-intellisense.aspx\"><font face=\"Calibri\" color=\"#0000ff\" size=\"3\">here<\/font><\/a><font face=\"Calibri\" size=\"3\">) will affect <i>VCCodeModel<\/i>.&nbsp; General information about <i>VCCodeModel<\/i> can be found <\/font><a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/t41260xs(VS.80).aspx\"><font face=\"Calibri\" color=\"#0000ff\" size=\"3\">here<\/font><\/a><font face=\"Calibri\" size=\"3\">.<\/font><\/p>\n<p class=\"MsoNormal\"><b><span>Improvements<\/p>\n<p><\/span><\/b><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Because of our new incremental update architecture, <i>VCCodeModel<\/i> implicitly gets certain benefits:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b>Availability:<\/b> Once initial population is done,<i> VCCodeModel<\/i> is pretty much always available. That is a positive result of design decisions to parse files independently. No change of a single file (even the omnipresent windows.h, if you like) will cause &ldquo;rebuild of the world&rdquo;. That means, if issued, calls to <b><i>VCCodeModel.Synchronize<\/i><\/b> will return almost instantly.<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b>Reliability:<\/b> We no longer use the old <i>NCB<\/i> <i>database<\/i>. Instead, we now use the same redistributable SQL CE components that we provide to our end-users.&nbsp; Suggestions to &ldquo;delete your .ncb file&rdquo; (due to DB corruption) in order to restore functionality of <i>Browsing\/Intellisense<\/i> are a thing of the past.&nbsp; <b><\/p>\n<p><\/b><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b>Independence from a macro state:<\/b> Prior to <i>Visual Studio 2010<\/i>, a file snapshot was taken in a certain undefined macro state. Depending on macro state active in a translation unit at the moment file contents were analyzed, certain constructs would or would not make it into the <i>NCB database<\/i>.&nbsp; That caused a lot of confusion.&nbsp; In <i>Visual Studio 2010<\/i> macro state is ignored and all source file declarations and definitions make it into database, and therefore into <i>VCCodeModel<\/i>.<b><\/p>\n<p><\/b><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>\/\/ Both A and B will make it into database and VCCodeModel, no matter if X is<br \/>\/\/ defined or not.<\/span><span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>#ifdef<\/span><span> X<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>class<\/span><span> A {};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>#else<\/span><span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>class<\/span><span> B {};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>#endif<\/span><span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">See <b>Dealing with preprocessor conditional directives <\/b>and<b> Hint files <\/b>sections of Thierry&rsquo;s <\/font><a href=\"http:\/\/blogs.msdn.com\/vcblog\/archive\/2009\/08\/12\/tag-parsing-c.aspx\"><font face=\"Calibri\" size=\"3\">post<\/font><\/a><font face=\"Calibri\" size=\"3\">.<\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b>Improved eventing model:<i> <\/i><\/b><i>VCCodeModel<\/i> edit <i>Events<\/i> are more precise and correct, thanks to improvements to our <i>code difference<\/i> algorithms.&nbsp; The new <i>difference<\/i> algorithms have better understanding of user edits.&nbsp; This is especially true in the presence of templates. This improves the reliability of the<i> Visual C++ Wizards <\/i>and clients who listen to <i>VCCodeModel Events<\/i>.<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b>Performance<i>: <\/i><\/b><i>VCCodeModel<\/i> is faster in scenarios where an object reference is taken and passed through external third party code (your code!) which may perform looped inquiries. This is thanks to some targeted caching we added to<i> VCCodeModel<\/i>.&nbsp; All clients should benefit from this since many of <i>VCCodeModel<\/i> services are implemented using its externally exposed APIs for correctness.<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><b><span>Limitations<\/p>\n<p><\/span><\/b><\/p>\n<p><font face=\"Calibri\" size=\"3\">The aforementioned benefits are primarily brought about by the design decision to treat every single file independently and through some targeted performance work.&nbsp; However, a downside that this design decision exposes is a lack of absolute precision in full symbol resolution in <i>Visual Studio 2010 Browsing<\/i>. It applies the following limitations on <i>VCCodeModel<\/i>: <\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b>No symbol resolution<\/b>: Type Strings for functions (return type), typedefs, base classes, macro definitions (except those specified in hint files) and parameters are coming directly from source code. They are no longer resolved by compiler as it used to be.&nbsp; This problem may surface if a caller wants to figure out precisely what type a function is returning:<\/font><\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><b><font size=\"3\"><font face=\"Calibri\">Example 1:<\/p>\n<p><\/font><\/font><\/b><\/p>\n<p class=\"MsoNormal\"><span>using<\/span><span> <span>namespace<\/span> X;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>using namespace <\/span><span>Z;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Type foo() { <span>return<\/span> Type(); }<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">The Type String for <b><i>VCCodeFunction <\/i><\/b>object referring to function <\/font><span>foo<\/span><font face=\"Calibri\"> is <\/font><span>Type<\/span><font face=\"Calibri\">. We don&rsquo;t really know if it is <\/font><span>X::Type<\/span><font face=\"Calibri\">, global <\/font><span>Type<\/span><font face=\"Calibri\"> or <\/font><span>Z::Type<\/span><font face=\"Calibri\">. Note that <\/font><span>using namespace<\/span><font face=\"Calibri\"> in this&nbsp;sample, should not necessarily be in same file, it can be in a header (far away). Without building the full translation unit, there&rsquo;s no efficient way to resolve the symbol <\/font><span>Type<\/span><font face=\"Calibri\"> deterministically and to maintain the performance improvements that our customers desire and that we have achieved with this new design. <b><\/p>\n<p><\/b><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><b><font size=\"3\"><font face=\"Calibri\">Example 2:<\/p>\n<p><\/font><\/font><\/b><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">File.h<\/font><\/p>\n<p class=\"MsoNormal\"><span>class<\/span><span> Base {};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">File2.h <span><\/p>\n<p><\/span><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span>namespace<\/span><span> A {<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>class<\/span> Base {};<\/span><br \/><span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>namespace<\/span><span> B { <\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>class<\/span> Base {};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">File.cpp<\/font><\/p>\n<p class=\"MsoNormal\"><span>#include<\/span><span> &ldquo;a_header_including_many_headers_and_introducing_using_directives.h&rdquo;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>class<\/span><span> Derived : Base <span>\/\/ Which Base is that? Base, A::Base or B::Base?<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>{};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Lack of precise fully-qualified symbol resolution affects<b> <i>TypeString<\/i><\/b> properties of <b><i>VCCodeParameter<\/i><\/b>,<b> <i>VCCodeTypedef<\/i><\/b> and <b><i>FullName<\/i><\/b> property of <b><i>VCCodeBase<\/i><\/b>.It also indirectly affects several APIs of the <b><i>CodeTypeRef<\/i><\/b> object that is used as a link between object in source code and type.<\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\"><i>VCCodeModel <\/i>provides heuristic APIs that attempt to resolve a name to a type, even if name is not fully qualified. For incompletely qualified names (like <\/font><span>&rdquo;Type&rdquo;<\/span><font face=\"Calibri\">, if <\/font><span>Type<\/span><font face=\"Calibri\"> belongs to namespace <\/font><span>X<\/span><font face=\"Calibri\">) <b><i>&nbsp;VCCodeModel.CodeTypeFromFullName<\/i><\/b> and <b><i>VCCodeModel.CodeElementFromFullName<\/i><\/b> prefer names defined at global scope and only resolve to a name defined in a namespace if a global one is not found. <\/font><\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">We&rsquo;ve added a helper API called <b><i>VCCodeModel.CodeElementFromFullName2<\/i><\/b>&nbsp; in <i>\nVisual Studio 2010<\/i> to help clients detect this ambiguity. See below.<\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b>No code elements from imported assemblies in C++\/CLI:<\/b> Code elements from imported assemblies are not added to the <i>Browsing database<\/i>. As a consequence, the types coming from these assemblies would not be resolved.&nbsp; For example, if you have a function with a parameter type specified as <\/font><span>Exception<\/span><font face=\"Calibri\"> in source code,<i> VCCodeModel<\/i> won&rsquo;t be able to resolve it to <\/font><span>System::Exception<\/span><font face=\"Calibri\">, since currently such class is not present in database.<\/font><\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b>We&rsquo;ve removed Managed C++ support from VCCodeModel in Dev10: <\/b>Support for <i>C++\/CLI <\/i>is still there.<b> <\/b><\/font><\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><b><span>New APIs in Visual Studio 2010<\/p>\n<p><\/span><\/b><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">We have introduced the following APIs to <i>VCCodeModel<\/i> in <i>Visual Studio 2010<\/i>. All APIs are additions to the <b><i>VCCodeModel <\/i><\/b>interface: <\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b><i>CodeElementFromFullName2<\/i><\/b>: Is identical to <b><i>CodeElementFromFullName<\/i><\/b>, except that it will disregard namespaces during lookup. Because there is no symbol resolution in <i>Visual Studio 2010 <\/i>version of <i>VCCodeModel<\/i> it is sometimes beneficial to know whether a particular symbol is ambiguous. The primary source of ambiguity in <i>VCCodeModel<\/i> is <\/font><span>using namespace<\/span><font face=\"Calibri\"> directives. <b><i>CodeElementFromFullName2<\/i> <\/b>API looks up the name disregarding namespace. For the following source code:<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span>class<\/span><span> X {};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>namespace<\/span><span> NS1 {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>class<\/span> X {};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>namespace<\/span> NS2 {<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>class<\/span> X {};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>}<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">Calls to <\/font><span>VCCodeModel.CodeElementFromFullName2(&ldquo;X&rdquo;)<\/span><font face=\"Calibri\"> will yield<\/font><span> {X; NS1::X; NS1::NS2::X}<\/span><font face=\"Calibri\">. <\/font><\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b><i>CodeTypeFromFullName2<\/i><\/b>: Is identical to <b><i>CodeTypeFromFullName<\/i><\/b> except that it will attempt typedef resolution. That is, for the following code:<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span>class<\/span><span> X {};<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>typedef<\/span><span> X TD;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">call to <\/font><span>VCCodeModel.CodeTypeFromFullName2(&ldquo;TD&rdquo;)<\/span><font face=\"Calibri\"> will yield class <\/font><span>X<\/span><font face=\"Calibri\">.<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b><i>IsSynchronized<\/i>:<\/b> returns true or false depending on whether <i>VCCodeModel <\/i>is in sync with solution&rsquo;s source code. Useful for avoiding blocking the calling thread for an undefined period of time while <i>Browsing<\/i> <i>database<\/i> is being populated.<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b><i>SynchronizeFiles<\/i><\/b>: If\n<i>VCCodeModel <\/i>is not in sync with source code, it is not safe to query for a <b><i>VCFileCodeModel<\/i><\/b> for a project file (caller will get null reference if project files are not yet registered in <i>Browsing<\/i> <i>database<\/i>). Call to<b><i> SynchronizeFiles<\/i><\/b> makes sure that <b><i>FileCodeModel<\/i><\/b> property on a project file is guaranteed to be not null.<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><span><font face=\"Calibri\" size=\"3\">&bull;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><b><i>SynchronizeCancellable<\/i><\/b>: if caller invokes this API while <i>Browsing database<\/i> is being populated, and there&rsquo;s significant delay till population completes (for example: initial population of solution <i>Browsing database<\/i>), the user will see a dialog box with a progress bar.&nbsp; The dialog box also allows users to cancel wait and API will exit unblocking thread. <\/font><\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">We&rsquo;re looking forward to hearing your feedback.&nbsp; Any suggestions, comments and feedback about what can we do to make <i>VCCodeModel<\/i> better are welcome.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Vytas\/Visual C++<\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello, I&rsquo;m Vytautas Leonavi&#269;ius, a developer on the Visual C++ IDE team. Today, I&rsquo;d like to discuss how the new principles we&rsquo;re applying to code browsing in Visual Studio 2010 (see here and here) will affect VCCodeModel.&nbsp; General information about VCCodeModel can be found here. Improvements Because of our new incremental update architecture, VCCodeModel implicitly [&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":[6],"class_list":["post-4233","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-ide"],"acf":[],"blog_post_summary":"<p>Hello, I&rsquo;m Vytautas Leonavi&#269;ius, a developer on the Visual C++ IDE team. Today, I&rsquo;d like to discuss how the new principles we&rsquo;re applying to code browsing in Visual Studio 2010 (see here and here) will affect VCCodeModel.&nbsp; General information about VCCodeModel can be found here. Improvements Because of our new incremental update architecture, VCCodeModel implicitly [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/4233","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=4233"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/4233\/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=4233"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=4233"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=4233"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}