{"id":25759,"date":"2020-03-27T15:00:44","date_gmt":"2020-03-27T15:00:44","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=25759"},"modified":"2021-06-08T18:03:29","modified_gmt":"2021-06-08T18:03:29","slug":"announcing-full-support-for-a-c-c-conformant-preprocessor-in-msvc","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/announcing-full-support-for-a-c-c-conformant-preprocessor-in-msvc\/","title":{"rendered":"Announcing full support for a C\/C++ conformant preprocessor in MSVC"},"content":{"rendered":"<p><em>Update June 8, 2021: The <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/c11-and-c17-standard-support-arriving-in-msvc\">C11 and C17 announcement post<\/a> has instructions on how to get the latest Windows SDK that works with the conformant preprocessor.<\/em><\/p>\n<p>We are excited to announce full support for a conformant preprocessor in the MSVC toolset starting with Visual Studio 2019 version 16.6 Preview 2.<\/p>\n<p>Since the original <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/msvc-preprocessor-progress-towards-conformance\/\">blog post<\/a> announcing preprocessor conformance changes, we\u2019ve come a long way and are now ready to announce the completion of the C\/C++ conformant preprocessor and its move to a non-experimental, fully supported state via the <code>\/Zc:preprocessor<\/code> switch. Alongside standard conformance, the preprocessor also supports C++20\u2019s <code>__VA_OPT__<\/code> and is also available in the C language mode.<\/p>\n<h2>What\u2019s new:<\/h2>\n<p>To reach conformance, a couple of additional features have been added to the preprocessor and MSVC compiler, including a variety of bug fixes, <code>__VA_OPT__<\/code>, and <code>_Pragma<\/code> support.<\/p>\n<p>Bugfixes involving various parts of the preprocessor, from <a href=\"https:\/\/developercommunity.visualstudio.com\/content\/problem\/897371\/experimental-preprocessor-in-vs2019-preview-incorr.html\">parameter expansion<\/a> and special macro names like <a href=\"https:\/\/developercommunity.visualstudio.com\/content\/problem\/734005\/-funcsig-doesnt-resolve-non-type-template-paramete.html\">__FUNCSIG__<\/a> to reporting <a href=\"https:\/\/developercommunity.visualstudio.com\/content\/problem\/362391\/preprocessor-warning-should-be-an-error.html\">arity errors<\/a> and line number fixes. Special thanks to Edward Diener for providing a lot of valuable feedback!<\/p>\n<h2>__VA_OPT__<\/h2>\n<p><code>__VA_OPT__<\/code> is a new feature of variadic macros in C++20. It lets you optionally insert tokens depending on if a variadic macro is invoked with additional arguments. An example usage is comma elision in a standardized manner.<\/p>\n<pre class=\"lang:default decode:true\">#define M(X, \u2026) X __VA_OPT__(,) __VA_ARGS__\r\nM(3) \/\/ expands to 3\r\nM(3, 4) \/\/ expands to 3, 4<\/pre>\n<h2>_Pragma<\/h2>\n<p>The _Pragma operator has been one of the long-standing deficiencies of the preprocessor, and a blocker in being standard conformant in C++ and C99. Though MSVC had the non-conformant __pragma, the semantics differ in that _Pragma takes a string literal as its parameter instead of a series of preprocessor tokens. This feature is now implemented.<\/p>\n<pre class=\"lang:default decode:true\">_Pragma(\u201conce\u201d)\r\n#define GUARD _Pragma(\u201conce\u201d)<\/pre>\n<h3>Miscellaneous<\/h3>\n<p>There were some <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/c-modules-conformance-improvements-with-msvc-in-visual-studio-2019-16-5\/\">contextual keyword changes relating to modules<\/a>. These changes unblock further C++20 modules work.<\/p>\n<p>Preprocessor-only output (via \/E and \/P) is now prettier, reducing the amount of line directives and fixing some formatting <a href=\"https:\/\/developercommunity.visualstudio.com\/content\/problem\/523058\/lines-incorrectly-joined-by-multi-line-macro-invoc.html\">issues<\/a>.<\/p>\n<h2>Enabling the conformant preprocessor in your environment<\/h2>\n<p>All that is needed to use the conformant preprocessor is to add <code>\/Zc:preprocessor<\/code> to your compilation flags. The flag is available in C and C++ language modes. It works with any language level, but we plan to enable it for <code>\/std:c++latest<\/code> in a future release.<\/p>\n<table>\n<tbody>\n<tr>\n<td>Language mode<\/td>\n<td>\/Zc:preprocessor<\/td>\n<\/tr>\n<tr>\n<td>\/std:c++14<\/td>\n<td>Not implied<\/td>\n<\/tr>\n<tr>\n<td>\/std:c++17<\/td>\n<td>Not implied<\/td>\n<\/tr>\n<tr>\n<td>\/std:c++latest<\/td>\n<td>Implied in a future update (Not implied in VS 2019 v16.6)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The conformant preprocessor can be tested by checking if the macro <code>_MSVC_TRADITIONAL<\/code> is defined and set to 0.<\/p>\n<pre class=\"lang:default decode:true \">#if defined(_MSVC_TRADITIONAL) &amp;&amp; _MSVC_TRADITIONAL\r\n\/\/ old behavior\r\n#else\r\n\/\/ new behavior\r\n#endif<\/pre>\n<p>The legacy preprocessor is not going anywhere, it will continue to serve as a compatibility layer for old code, but it will only be serviced with the intention of keeping old code working. Additionally, the <code>\/experimental:preprocessor<\/code> switch is still available and will activate <code>\/Zc:preprocessor<\/code> in VS 2019 v16.6 but will be removed in a future release. Any projects that have been configured to use the experimental switch should migrate to the supported version.<\/p>\n<h2>What\u2019s next:<\/h2>\n<p>Improved diagnostics are in the works, which will provide a better expansion context for macro invocation and errors.<\/p>\n<p>This feature is not currently implied by any other flags, but we are planning to include it in \/std:c++latest once we stabilize the public SDK headers from using non-conformant macros. Using the latest Windows SDK is advised, as many of the noisy warnings are fixed in later SDK versions.<\/p>\n<h2>Call to Action<\/h2>\n<p>Let us know how the conformant preprocessor works for you! Get it in Visual Studio 2019 version 16.6 Preview 2 (please see <a href=\"https:\/\/visualstudio.microsoft.com\/vs\/preview\/\">https:\/\/visualstudio.microsoft.com\/vs\/preview\/<\/a> for download links) and try it out.<\/p>\n<p>As always, we welcome your feedback. We can be reached via the comments below or via email (visualcpp@microsoft.com). If you encounter problems with Visual Studio or MSVC, or have a suggestion for us, please let us know through Help &gt; Send Feedback &gt; Report A Problem \/ Provide a Suggestion in the product, or via <a href=\"https:\/\/developercommunity.visualstudio.com\/\">Developer Community<\/a>. You can also find us on Twitter (<a href=\"https:\/\/twitter.com\/visualc\">@VisualC<\/a>).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Update June 8, 2021: The C11 and C17 announcement post has instructions on how to get the latest Windows SDK that works with the conformant preprocessor. We are excited to announce full support for a conformant preprocessor in the MSVC toolset starting with Visual Studio 2019 version 16.6 Preview 2. Since the original blog post [&hellip;]<\/p>\n","protected":false},"author":17039,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[270],"tags":[],"class_list":["post-25759","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcement"],"acf":[],"blog_post_summary":"<p>Update June 8, 2021: The C11 and C17 announcement post has instructions on how to get the latest Windows SDK that works with the conformant preprocessor. We are excited to announce full support for a conformant preprocessor in the MSVC toolset starting with Visual Studio 2019 version 16.6 Preview 2. Since the original blog post [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/25759","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\/17039"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=25759"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/25759\/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=25759"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=25759"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=25759"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}