{"id":107998,"date":"2023-03-31T07:00:00","date_gmt":"2023-03-31T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=107998"},"modified":"2023-03-30T21:15:50","modified_gmt":"2023-03-31T04:15:50","slug":"20230331-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20230331-00\/?p=107998","title":{"rendered":"What is this <CODE>[uuid(&#8230;)]<\/CODE> in front of my C++ class declaration?"},"content":{"rendered":"<p>A customer was dealing with some legacy code, and when they included one of their header files in a new project:<\/p>\n<pre>\/\/ foo.h\r\n\r\n[uuid(a6107c25-4c22-4a12-8440-7eb8f5972e50)]\r\nclass Widget : public IWidget\r\n{\r\n    \/* ... *\/\r\n};\r\n<\/pre>\n<p>They ran into a weird compiler error:<\/p>\n<pre style=\"white-space: pre-wrap;\">error C2337: 'uuid': attribute not found\r\nerror C3688: invalid literal suffix 'a6107c25'; literal operator or literal operator template 'operator \"\"a6107c25' not found\r\n<\/pre>\n<p>First question: What is this <code>[uuid(...)]<\/code> notation anyway?<\/p>\n<p>Answer: It is <a href=\"https:\/\/docs.microsoft.com\/cpp\/windows\/attributes\/uuid-cpp-attributes\"> a Visual C++ nonstandard extension<\/a> that associates a UUID with a type, extractable by the <code>__uuid<\/code> extension. This is part of a larger set of <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/windows\/attributes\/cpp-attributes-com-net\"> attributes designed for COM and .NET<\/a>.<\/p>\n<p>Okay, so now that we know what it is, why isn&#8217;t it working?<\/p>\n<p>If you set the <code>\/permissive-<\/code> compiler flag, then the Visual C++ compiler no longer supports this nonstandard attribute syntax. This is mentioned <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/permissive-standards-conformance?view=msvc-170#use-of-atl-attributes\"> in the documentation for <code>\/permissive-<\/code><\/a>:<\/p>\n<blockquote class=\"q\">\n<p>Microsoft-specific ATL attributes can cause issues under <code>\/permissive-<\/code>:<\/p>\n<pre>\/\/ Example 1\r\n[uuid(\"594382D9-44B0-461A-8DE3-E06A3E73C5EB\")]\r\nclass A {};\r\n<\/pre>\n<p>You can fix the issue by using the <code>__declspec<\/code> form instead:<\/p>\n<pre>\/\/ Fix for example 1\r\nclass __declspec(uuid(\"594382D9-44B0-461A-8DE3-E06A3E73C5EB\")) B {};\r\n<\/pre>\n<\/blockquote>\n<p>The <code>__declspec(uuid(...))<\/code> syntax is still nonstandard, but at least it&#8217;s nonstandard in a standard-compliant way: Identifiers which begins with two underscores are reserved for the implementation.<\/p>\n<p>Final mystery: Why did this problem show up all of a sudden? Their other projects worked fine.<\/p>\n<p>The reason is that the customer created a new project, and <a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/msvc-conformance-improvements-in-visual-studio-2017-version-15-5\/#conformance-mode-on-by-default-for-new-projects\"> <code>\/permissive-<\/code> is the default for new projects<\/a>. The corresponding property in the <code>.vcxproj<\/code> file is <code>&lt;ConformanceMode&gt;true&lt;\/ConformanceMode&gt;<\/code>.<\/p>\n<p>And the solution is to update the header file to use <code>__declspec(uuid(...))<\/code> instead of <code>[uuid(...)]<\/code>:<\/p>\n<pre>\/\/ foo.h\r\n\r\nclass\r\n__declspec(uuid(\"a6107c25-4c22-4a12-8440-7eb8f5972e50\"))\r\nWidget : public IWidget\r\n{\r\n    \/* ... *\/\r\n};\r\n<\/pre>\n<p>You can use the Windows-defined macro <code>DECLSPEC_UUID<\/code> as an alternative:<\/p>\n<pre>\/\/ foo.h\r\n\r\nclass\r\nDECLSPEC_UUID(\"a6107c25-4c22-4a12-8440-7eb8f5972e50\")\r\nWidget : public IWidget\r\n{\r\n    \/* ... *\/\r\n};\r\n<\/pre>\n<p>The macro allows for more flexibility since it allows other toolchains to redefine the macro to expand to whatever makes sense for them (either some other custom extension, or simply nothing at all).<\/p>\n<p>In both cases, note the placement of the declaration: It goes immediately before the name being declared, after the type specifier keyword <code>struct<\/code> or <code>class<\/code>.<\/p>\n<p>If you are not at liberty to update the header file, then you&#8217;ll have to disable <code>\/permissive-<\/code> in order to get the header file to compile.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s an old nonstandard syntax that you should try to move away from.<\/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],"class_list":["post-107998","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It&#8217;s an old nonstandard syntax that you should try to move away from.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107998","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=107998"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107998\/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=107998"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=107998"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=107998"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}