{"id":33001,"date":"2023-10-11T14:58:31","date_gmt":"2023-10-11T14:58:31","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=33001"},"modified":"2023-10-11T14:58:31","modified_gmt":"2023-10-11T14:58:31","slug":"structured-diagnostics-in-the-new-problem-details-window","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/structured-diagnostics-in-the-new-problem-details-window\/","title":{"rendered":"Structured Diagnostics in the New Problem Details Window"},"content":{"rendered":"<p>Massive compiler errors which seem impossible to navigate are the bane of many C++ developers\u2019 lives. It\u2019s up to tools to provide a better experience to help you comprehend diagnostics and understand how to fix the root issue. I wrote <a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2022\/p2429r0.pdf\">Concepts Error Messages for Humans<\/a> to explore some of the design space and now, due to the hard work of many folks working on Visual Studio, we have a better experience to share with you all. You can read about some of the work which has led up to these changes in Xiang Fan\u2019s blog post on the <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/the-future-of-c-compiler-diagnostics-in-msvc-and-visual-studio\/\">future of C++ diagnostics in MSVC and Visual Studio<\/a>.<\/p>\n<p>In Visual Studio 2022 version 17.8 Preview 3, if you run a build using MSVC and an MSBuild project, entries in the Error List which have additional information available will show an icon in a new column named Details:<\/p>\n<p><img decoding=\"async\" width=\"559\" height=\"94\" class=\"wp-image-33002\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-1.png\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-1.png 559w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-1-300x50.png 300w\" sizes=\"(max-width: 559px) 100vw, 559px\" \/><\/p>\n<p>If you click this button, a new Problem Details window will open up. By default this will be in the same place as the Error List, but if you move it around, Visual Studio will remember where you put it.<\/p>\n<p><img decoding=\"async\" width=\"468\" height=\"174\" class=\"wp-image-33003\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-description-automatica.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-description-automatica.png 468w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-description-automatica-300x112.png 300w\" sizes=\"(max-width: 468px) 100vw, 468px\" \/><\/p>\n<p>This Problem Details window provides you with detailed, structured information about why a given problem occurred. If we look at this information we might think, okay, why could void <code>pet(dog)<\/code> not be called? If you click the arrow next to it, you can see why:<\/p>\n<p><img decoding=\"async\" width=\"465\" height=\"204\" class=\"wp-image-33004\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-program-description-au.png\" alt=\"A screenshot of a computer program Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-program-description-au.png 465w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-program-description-au-300x132.png 300w\" sizes=\"(max-width: 465px) 100vw, 465px\" \/><\/p>\n<p>In a similar way we can expand out other arrows to find out more information about our errors. This example is produced from code which uses C++20 Concepts and the Problem Details window gives you a way to understand the structure of Concepts errors.<\/p>\n<p><img decoding=\"async\" width=\"460\" height=\"331\" class=\"wp-image-33005\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-description-automatica-1.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-description-automatica-1.png 460w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-description-automatica-1-300x216.png 300w\" sizes=\"(max-width: 460px) 100vw, 460px\" \/><\/p>\n<p>For those who would like to play around with this example, the code required to produce these errors is:<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">struct dog {};\r\nstruct cat {};\r\n\r\nvoid pet(dog);\r\nvoid pet(cat);\r\n\r\ntemplate &lt;class T&gt;\r\nconcept has_member_pet = requires(T t) { t.pet(); };\r\n\r\ntemplate &lt;class T&gt;\r\nconcept has_default_pet = T::is_pettable;\r\n\r\ntemplate &lt;class T&gt;\r\nconcept pettable = has_member_pet&lt;T&gt; or has_default_pet&lt;T&gt;;\r\n\r\nvoid pet(pettable auto t);\r\n\r\nstruct lizard {};\r\n\r\nint main() {\r\n    pet(lizard{});\r\n}<\/code><\/pre>\n<p>Make sure you compile with <code>\/std:c++20<\/code> to enable Concepts support.<\/p>\n<h2>Output Window<\/h2>\n<p>As part of this work we have also made the Output Window visualize any hierarchical structure in the output diagnostics. For example, here in an excerpt produced by building the previous example:<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">1&gt;Source.cpp(18,6): \r\n1&gt;or       'void pet(_T0)' \r\n1&gt;Source.cpp(23,5): \r\n1&gt;the associated constraints are not satisfied \r\n1&gt;\tSource.cpp(18,10): \r\n1&gt;\tthe concept 'pettable&lt;lizard&gt;' evaluated to false \r\n1&gt;\t\tSource.cpp(16,20): \r\n1&gt;\t\tthe concept 'has_member_pet&lt;lizard&gt;' evaluated to false \r\n1&gt;\t\t\tSource.cpp(10,44): \r\n1&gt;\t\t\t'pet': is not a member of 'lizard' \r\n1&gt;\t\t\tSource.cpp(20,8): \r\n1&gt;\t\t\tsee declaration of 'lizard' \r\n1&gt;\t\tSource.cpp(16,41): \r\n1&gt;\t\tthe concept 'has_default_pet&lt;lizard&gt;' evaluated to false \r\n1&gt;\t\t\tSource.cpp(13,30): \r\n1&gt;\t\t\t'is_pettable': is not a member of 'lizard' \r\n1&gt;\t\t\tSource.cpp(20,8): \r\n1&gt;\t\t\tsee declaration of 'lizard' <\/code><\/pre>\n<p>This change makes it much easier to scan large sets of diagnostics without getting lost.<\/p>\n<h2>Code Analysis<\/h2>\n<p>The Problem Details window is now also used for code analysis warnings which have associated Key Events. For example, consider this code which could potentially result in a use-after-move:<\/p>\n<pre class=\"prettyprint language-default\"><code class=\"language-default\">#include &lt;string&gt; \r\nvoid eat_string(std::string&amp;&amp;); \r\nvoid use_string(std::string); \r\nvoid oh_no(bool should_eat, bool should_reset) { \r\n    std::string my_string{ \"meow\" }; \r\n    bool did_reset{ false }; \r\n \r\n    if (should_eat) { \r\n        eat_string(std::move(my_string));  \r\n    } \r\n \r\n    if (should_reset) { \r\n        did_reset = true; \r\n        my_string = \"the string is reset\";  \r\n    } \r\n \r\n    if (did_reset &amp;&amp; !should_reset) { \r\n        eat_string(std::move(my_string)); \r\n    } \r\n\r\n    use_string(my_string); \r\n}  <\/code><\/pre>\n<p>In the case that <code>should_eat<\/code> is <code>true<\/code> and <code>should_reset<\/code> is <code>false<\/code>, <code>my_string<\/code> will be used after being moved, likely resulting in undesirable behaviour.<\/p>\n<p>Fortunately, our static analyzer catches this issue, creating an entry in the Error List:<\/p>\n<p><img decoding=\"async\" width=\"477\" height=\"92\" class=\"wp-image-33006\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-error-message-descript.png\" alt=\"A screenshot of a computer error message Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-error-message-descript.png 477w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-error-message-descript-300x58.png 300w\" sizes=\"(max-width: 477px) 100vw, 477px\" \/><\/p>\n<p>See that icon in the Details column? That means there\u2019s extra information. Let\u2019s have a look:<\/p>\n<p><img decoding=\"async\" width=\"452\" height=\"185\" class=\"wp-image-33007\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-description-automatica-2.png\" alt=\"A screenshot of a computer Description automatically generated\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-description-automatica-2.png 452w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/a-screenshot-of-a-computer-description-automatica-2-300x123.png 300w\" sizes=\"(max-width: 452px) 100vw, 452px\" \/><\/p>\n<p>This tells us the process which the static analyzer followed to reach its conclusion that a moved-from object may be used in this program. For a small function like this we likely could have worked this out ourselves, but for larger or more complex functions, Key Events can help you understand why you\u2019re getting a warning for your code.<\/p>\n<p>You can learn more about Key Events in Hwi-Sung Im\u2019s blog post on <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/microsoft-cpp-code-analysis-warnings-with-key-events\/\">code analysis warnings with Key Events<\/a>.<\/p>\n<h2>Configuration<\/h2>\n<p>By default, the Problem Details window will also open when you double click or press enter on an Error List entry which has associated details. This can be configured at Tools &gt; Options &gt; Text Editor &gt; C\/C++ &gt; Advanced &gt; Error List &gt; Show Problem Details on double click.<\/p>\n<p><img decoding=\"async\" width=\"801\" height=\"461\" class=\"wp-image-33008\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-7.png\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-7.png 801w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-7-300x173.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-7-768x442.png 768w\" sizes=\"(max-width: 801px) 100vw, 801px\" \/><\/p>\n<p>The entire feature can be enabled or disabled at Project &gt; Properties &gt; Advanced &gt; Enable MSVC Structured Output. You can affect several projects by creating a <a href=\"https:\/\/learn.microsoft.com\/en-us\/visualstudio\/msbuild\/customize-by-directory?view=vs-2022\">Directory.Build.props<\/a> file with the <code>UseStructuredOutput<\/code> property defined to true or false.<\/p>\n<p><img decoding=\"async\" width=\"781\" height=\"541\" class=\"wp-image-33009\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-8.png\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-8.png 781w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-8-300x208.png 300w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2023\/10\/word-image-33001-8-768x532.png 768w\" sizes=\"(max-width: 781px) 100vw, 781px\" \/><\/p>\n<h2>How it Works<\/h2>\n<p>This work leverages the <a href=\"https:\/\/sarifweb.azurewebsites.net\/\">SARIF<\/a> (Static Analysis Results Interchange Format) standard. This is a JSON-based format for expressing diagnostics in a structured way which enables the compiler to preserve the hierarchy inherent in many diagnostics when sending information to the IDE.<\/p>\n<p>No additional compiler flags are required for accessing the new experience, but if you want the compiler to produce diagnostics in SARIF in order to use the results with external tools, you can pass the <code>\/experimental:log&lt;output_directory_name&gt;<\/code> flag to MSVC.<\/p>\n<h2>Call for action<\/h2>\n<p>Please install the latest <a href=\"https:\/\/visualstudio.microsoft.com\/vs\/preview\/\">Visual Studio 2022 Preview<\/a> to try out the new diagnostics experience. After you\u2019ve tried it, please let us know what you think through e-mail at\u00a0<a href=\"mailto:visualcpp@microsoft.com\">visualcpp@microsoft.com.<\/a><\/p>\n<p>If you encounter other problems with VS 2022 please let us know via the <a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/how-to-report-a-problem-with-visual-studio?view=vs-2019\" target=\"_blank\" rel=\"noopener\">Report a Problem<\/a>\u00a0option, either from the installer or the Visual Studio IDE itself. For suggestions or bug reports, let us know through\u00a0<a href=\"https:\/\/developercommunity.visualstudio.com\/\" target=\"_blank\" rel=\"noopener\">DevComm.<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Massive compiler errors which seem impossible to navigate are the bane of many C++ developers\u2019 lives. It\u2019s up to tools to provide a better experience to help you comprehend diagnostics and understand how to fix the root issue. I wrote Concepts Error Messages for Humans to explore some of the design space and now, due [&hellip;]<\/p>\n","protected":false},"author":706,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[270,1,239],"tags":[],"class_list":["post-33001","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcement","category-cplusplus","category-diagnostics"],"acf":[],"blog_post_summary":"<p>Massive compiler errors which seem impossible to navigate are the bane of many C++ developers\u2019 lives. It\u2019s up to tools to provide a better experience to help you comprehend diagnostics and understand how to fix the root issue. I wrote Concepts Error Messages for Humans to explore some of the design space and now, due [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/33001","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\/706"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=33001"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/33001\/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=33001"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=33001"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=33001"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}