CINXE.COM

C++/CLI keywords: Under the hood | Microsoft Learn

<!DOCTYPE html><html class="hasSidebar hasPageActions hasBreadcrumb conceptual has-default-focus theme-light" lang="en-us" dir="ltr" data-authenticated="false" data-auth-status-determined="false" data-target="docs" x-ms-format-detection="none"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta property="og:title" content="C++/CLI keywords: Under the hood" /> <meta property="og:type" content="website" /> <meta property="og:url" content="https://learn.microsoft.com/en-us/archive/blogs/hsutter/ccli-keywords-under-the-hood" /><meta property="og:image" content="https://learn.microsoft.com/en-us/media/open-graph-image.png" /> <meta property="og:image:alt" content="Microsoft Learn" /> <meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:site" content="@MicrosoftLearn" /> <meta name="color-scheme" content="light dark"><meta name="archived_blog_id" content="71903" /> <meta name="archived_blog_orig_url" content="https://blogs.msdn.microsoft.com/hsutter" /> <meta name="archived_blog_post_id" content="163" /> <meta name="author" content="kexugit" /> <meta name="breadcrumb_path" content="/archive/blogs/bread/toc.json" /> <meta name="depot_name" content="MSDN.blogs-archive" /> <meta name="document_id" content="0ff93625-9a76-66d1-19cf-c9e78896f347" /> <meta name="document_version_independent_id" content="9553f4df-c795-dedf-cd40-aaf19d218a5c" /> <meta name="feedback_help_link_type" content="" /> <meta name="feedback_help_link_url" content="" /> <meta name="feedback_product_url" content="" /> <meta name="feedback_system" content="None" /> <meta name="git_commit_id" content="5019655ffa733bb8ab1266cc2a6a7b70a1ecdfa6" /> <meta name="gitcommit" content="https://docs-archive.visualstudio.com/DefaultCollection/docs-archive-project/_git/blogs-archive-pr/commit/5019655ffa733bb8ab1266cc2a6a7b70a1ecdfa6?path=/blogs-archive/hsutter/ccli-keywords-under-the-hood.md&amp;_a=contents" /> <meta name="is_archived" content="true" /> <meta name="locale" content="en-us" /> <meta name="ms.author" content="Archiveddocs" /> <meta name="ms.date" content="11/23/2003" /> <meta name="ms.topic" content="Archived" /> <meta name="original_content_git_url" content="https://docs-archive.visualstudio.com/DefaultCollection/docs-archive-project/_git/blogs-archive-pr?path=/blogs-archive/hsutter/ccli-keywords-under-the-hood.md&amp;version=GBlive&amp;_a=contents" /> <meta name="page_type" content="conceptual" /> <meta name="ROBOTS" content="NOINDEX,NOFOLLOW" /> <meta name="schema" content="Conceptual" /> <meta name="site_name" content="Docs" /> <meta name="toc_rel" content="toc.json" /> <meta name="uhfHeaderId" content="MSDocsHeader-Archive" /> <meta name="updated_at" content="2024-09-25 03:21 AM" /> <meta name="word_count" content="2496" /> <meta name="persistent_id" content="68105190-1d6c-b25b-d358-6400dd73e593" /> <meta name="scope" content="Blogs" /><meta name="github_feedback_content_git_url" content="https://docs-archive.visualstudio.com/DefaultCollection/docs-archive-project/_git/blogs-archive-pr?path=/blogs-archive/hsutter/ccli-keywords-under-the-hood.md&version=GBlive&_a=contents" /><link href="https://learn.microsoft.com/en-us/archive/blogs/hsutter/ccli-keywords-under-the-hood" rel="canonical"><title>C++/CLI keywords: Under the hood | Microsoft Learn</title><link rel="stylesheet" href="/static/assets/0.4.028726178/styles/site-ltr.css"> <script id="msdocs-script"> var msDocs = {environment: { supportLevel: 'production', accessLevel: 'online', reviewFeatures: false, systemContent: true, azurePortalHostname: 'portal.azure.com', legacyHosting: false, siteName: 'learn', },data: { timeOrigin: Date.now(), contentLocale: 'en-us', contentDir: 'ltr', userLocale: 'en-us', userDir: 'ltr', pageTemplate: 'Conceptual', brand: '', context: {}, hasBinaryRating: false, feedbackHelpLinkType:'', feedbackHelpLinkUrl:'', standardFeedback: false, showFeedbackReport: false, enableTutorialFeedback: false, feedbackSystem: 'None', feedbackGitHubRepo: '', feedbackProductUrl: '',extendBreadcrumb: false,isEditDisplayable: false, hideViewSource: false, hasPageActions: true, hasPrintButton: true, hasBookmark: true, hasShare: true, isPermissioned: false, isPrivateUnauthorized: false,hasRecommendations: true,}, functions:{} }; </script><script src="https://wcpstatic.microsoft.com/mscc/lib/v2/wcp-consent.js"></script> <script src="https://js.monitor.azure.com/scripts/c/ms.jsll-4.min.js"></script><script src="/static/assets/0.4.028726178/global/deprecation.js"></script><script src="/static/assets/0.4.028726178/scripts/en-us/index-docs.js"></script></head> <body lang="en-us" dir="ltr"> <div class="header-holder has-default-focus"> <a href="#main" style="z-index: 1070" class="outline-color-text visually-hidden-until-focused position-fixed inner-focus focus-visible top-0 left-0 right-0 padding-xs text-align-center has-body-background" tabindex="1">Skip to main content</a><div hidden id="cookie-consent-holder" data-test-id="cookie-consent-container"></div> <div id="unsupported-browser" style=" background-color: white; color: black; padding: 16px; border-bottom: 1px solid grey;" hidden > <div style="max-width: 800px; margin: 0 auto;"> <p style="font-size: 24px">This browser is no longer supported.</p> <p style="font-size: 16px; margin-top: 16px;">Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.</p> <div style="margin-top: 12px;"> <a href="https://go.microsoft.com/fwlink/p/?LinkID=2092881 " style=" background-color: #0078d4; border: 1px solid #0078d4; color: white; padding: 6px 12px; border-radius: 2px; display: inline-block; ">Download Microsoft Edge</a> <a href="https://learn.microsoft.com/en-us/lifecycle/faq/internet-explorer-microsoft-edge" style=" background-color: white; padding: 6px 12px; border: 1px solid #505050; color: #171717; border-radius: 2px; display: inline-block; ">More info about Internet Explorer and Microsoft Edge</a> </div> </div> </div> <!-- liquid-tag banners global --> <!-- site header --> <header id="ms--site-header" data-test-id="site-header-wrapper" role="banner" itemscope="itemscope" itemtype="http://schema.org/Organization"> <div id="ms--mobile-nav" class="site-header display-none-tablet padding-inline-none gap-none" data-bi-name="mobile-header" data-test-id="mobile-header"></div> <div id="ms--primary-nav" class="site-header display-none display-flex-tablet" data-bi-name="L1-header" data-test-id="primary-header"></div> <div id="ms--secondary-nav" class="site-header display-none display-flex-tablet" data-bi-name="L2-header" data-test-id="secondary-header"></div> </header><div id="content-header" class="content-header uhf-container has-padding has-default-focus border-bottom-none" data-bi-name="content-header"> <div class="content-header-controls margin-xxs margin-inline-sm-tablet"> <button type="button" class="contents-button button button-sm margin-right-xxs" data-bi-name="contents-expand" aria-haspopup="true" data-contents-button> <span class="icon"><span class="docon docon-menu" aria-hidden="true"></span></span> <span class="contents-expand-title">Table of contents</span> </button> <button type="button" class="ap-collapse-behavior ap-expanded button button-sm" data-bi-name="ap-collapse" aria-controls="action-panel"> <span class="icon"><span class="docon docon-exit-mode" aria-hidden="true"></span></span> <span>Exit focus mode</span> </button> </div> </div><div id="disclaimer-holder" class="has-overflow-hidden has-default-focus"> <!-- liquid-tag banners sectional --> </div> </div> <div class="mainContainer uhf-container has-default-focus" data-bi-name="body"> <div class="columns has-large-gaps is-gapless-mobile "><div id="left-container" class="left-container is-hidden-mobile column is-one-third-tablet is-one-quarter-desktop"> <nav id="affixed-left-container" class="margin-top-sm-tablet position-sticky display-flex flex-direction-column" aria-label="Primary"></nav> </div><!-- .primary-holder --> <section class="primary-holder column is-two-thirds-tablet is-three-quarters-desktop"> <!--div.columns --> <div class="columns is-gapless-mobile has-large-gaps "><div id="main-column" class="column is-full is-8-desktop"> <main id="main" class="" role="main" data-bi-name="content" lang="en-us" dir="ltr"><!-- article-header --> <div id="article-header" class="background-color-body margin-top-sm-tablet margin-bottom-xs display-none-print"> <div class="display-flex align-items-center "><details id="article-header-breadcrumbs-overflow-popover" class="popover" data-for="article-header-breadcrumbs"> <summary class="button button-clear button-primary button-sm inner-focus" aria-label="All breadcrumbs"> <span class="icon"> <span class="docon docon-more"></span> </span> </summary> <div id="article-header-breadcrumbs-overflow" class="popover-content padding-none"> </div> </details> <bread-crumbs id="article-header-breadcrumbs" data-test-id="article-header-breadcrumbs" class="overflow-hidden flex-grow-1 margin-right-sm margin-right-md-tablet margin-right-lg-desktop margin-left-negative-xxs padding-left-xxs"></bread-crumbs><div id="article-header-page-actions" class="opacity-none margin-left-auto display-flex flex-wrap-no-wrap align-items-stretch"><a id="lang-link-tablet" class="button button-primary button-clear button-sm display-none display-inline-flex-tablet" title="Read in English" data-bi-name="language-toggle" data-read-in-link hidden> <span class="icon margin-none" aria-hidden="true" data-read-in-link-icon> <span class="docon docon-locale-globe"></span> </span> <span class="is-visually-hidden" data-read-in-link-text>Read in English</span> </a><button type="button" class="collection button button-clear button-sm button-primary display-none display-inline-flex-tablet" data-list-type="collection" data-bi-name="collection" title="Add to collection"> <span class="icon margin-none" aria-hidden="true"> <span class="docon docon-circle-addition"></span> </span> <span class="collection-status is-visually-hidden">Save</span> </button> <details class="popover popover-right" id="article-header-page-actions-overflow"> <summary class="justify-content-flex-start button button-clear button-sm button-primary" aria-label="More actions" title="More actions"> <span class="icon" aria-hidden="true"> <span class="docon docon-more-vertical"></span> </span> </summary> <div class="popover-content padding-xs"><button data-page-action-item="overflow-mobile" type="button" class="justify-content-flex-start button-block button-sm has-inner-focus button button-clear display-none-tablet" data-bi-name="contents-expand" data-contents-button data-popover-close> <span class="icon"> <span class="docon docon-editor-list-bullet" aria-hidden="true"></span> </span><span class="contents-expand-title">Table of contents</span></button><a id="lang-link-overflow" class="justify-content-flex-start button-sm has-inner-focus button button-clear button-block display-none-tablet" title="Read in English" data-bi-name="language-toggle" data-page-action-item="overflow-mobile" data-check-hidden="true" data-read-in-link hidden > <span class="icon" aria-hidden="true" data-read-in-link-icon> <span class="docon docon-locale-globe"></span> </span> <span data-read-in-link-text>Read in English</span> </a><button type="button" class="collection justify-content-flex-start button button-clear button-sm has-inner-focus button-block display-none-tablet" data-list-type="collection" data-bi-name="collection" title="Save" data-page-action-item="overflow-mobile" data-check-hidden="true" data-popover-close> <span class="icon" aria-hidden="true"> <span class="docon docon-circle-addition"></span> </span> <span class="collection-status">Save</span> </button> <button type="button" class="collection justify-content-flex-start button button-clear button-sm has-inner-focus button-block display-none-tablet" data-list-type="plan" data-bi-name="plan" title="Add to Plan" data-page-action-item="overflow-mobile" data-check-hidden="true" data-popover-close hidden> <span class="icon" aria-hidden="true"> <span class="docon docon-circle-addition"></span> </span> <span class="plan-status">Add to Plan</span> </button><div aria-hidden="true" class="margin-none" data-page-action-item="overflow-all"></div> <hr class="display-none-tablet margin-bottom-xxs margin-top-xxs" /> <h4 class="font-size-sm padding-left-xxs">Share via</h4> <a class="button button-clear button-sm button-block has-inner-focus text-decoration-none justify-content-flex-start share-facebook" data-bi-name="facebook" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-facebook-share font-size-md color-primary"></span> </span> <span class="margin-left-xxs">Facebook</span> </a> <a class="button button-clear button-sm has-inner-focus button-block text-decoration-none justify-content-flex-start share-twitter" data-bi-name="twitter" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-xlogo-share font-size-xxs"></span> </span> <span class="margin-left-xxs">x.com</span> </a> <a class="button button-clear button-sm has-inner-focus button-block text-decoration-none justify-content-flex-start share-linkedin" data-bi-name="linkedin" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-linked-in-logo font-size-sm color-primary"></span> </span> <span class="margin-left-xxs">LinkedIn</span> </a> <a class="button button-clear button-sm button-block has-inner-focus text-decoration-none justify-content-flex-start margin-bottom-xxs share-email" data-bi-name="email" data-page-action-item="overflow-all"> <span class="icon" aria-hidden="true"> <span class="docon docon-mail-message font-size-sm color-primary"></span> </span> <span class="margin-left-xxs">Email</span> </a><hr /> <button class="button button-block button-clear button-sm justify-content-flex-start has-inner-focus margin-top-xxs" title="Print" type="button" aria-label="Print" data-bi-name="print" data-page-action-item="overflow-all" data-popover-close data-print-page data-check-hidden="true"> <span class="icon" aria-hidden="true"> <span class="docon docon-print font-size-sm color-primary"></span> </span> <span class="margin-left-xxs">Print</span> </button> </div> </details> </div></div> </div> <!-- end article-header --><div> <button type="button" class="border contents-button button button-clear button-sm is-hidden-tablet has-inner-focus" data-bi-name="contents-expand" data-contents-button hidden> <span class="icon"> <span class="docon docon-editor-list-bullet" aria-hidden="true"></span> </span><span class="contents-expand-title">Table of contents</span></button> </div><!-- end mobile-contents button --> <div class="content "><h1 id="ccli-keywords-under-the-hood">C++/CLI keywords: Under the hood</h1><div class="display-flex justify-content-space-between align-items-center flex-wrap-wrap page-metadata-container"> <div class="margin-right-xxs"> <ul class="metadata page-metadata" data-bi-name="page info" lang="en-us" dir="ltr"><li>Article</li><li> <time class="is-invisible" data-article-date aria-label="Article review date" datetime="2003-11-23T00:00:00.000Z" data-article-date-source="ms.date">11/23/2003</time> </li></ul> </div></div><nav id="center-doc-outline" class="doc-outline is-hidden-desktop display-none-print margin-bottom-sm" data-bi-name="intopic toc" aria-label="In this article"> <h2 id="ms--in-this-article" class="title is-6 margin-block-xs">In this article</h2> </nav><!-- <content> --><p>C++/CLI specifies several keywords as extensions to ISO C++. The way they are handled<br> falls into five major categories, where only the first impacts the meaning of existing<br> ISO C++ programs.</p> <p><strong>1. Outright reserved words</strong></p> <p>As of this writing (November 22, 2003, the day after we released the candidate base<br> document), C++/CLI is down to only three reserved words:</p> <p>&nbsp; <strong>gcnew generic nullptr</strong></p> <p>An existing program that uses these words as identifiers and wants to use C++/CLI<br> would have to rename the identifiers. I'll return to these three again at the end.</p> <p>All the other keywords, below, are contextual keywords that do not conflict with identifiers.<br> Any legal ISO C++ program that already uses the names below as identifiers will continue<br> to work as before; these keywords are not reserved words.</p> <p><strong>2. Spaced keywords</strong></p> <p>One implementation technique we are using is to specify some keywords that include<br> embedded whitespace. These are safe: They can't possibly conflict with any user identifiers<br> because no C++ program can create an identifier that contains whitespace characters.<br> [I'll omit the obligatory reference to Bjarne's classic April Fool's joke article<br> on the whitespace operator. :-) But what I'm saying here is true, not a joke.]</p> <p>Currently these are:</p> <p>&nbsp; <strong>for each<br> enum class/struct<br> interface class/struct<br> ref class/struct<br> value class/struct</strong></p> <p>For example, "<strong>ref class</strong>" is a single token in the lexer, and programs<br> that have a type or variable or namespace named <strong>ref</strong> are entirely<br> unaffected. (Somewhat amazingly, even most <em>macros</em> named <strong>ref</strong> are<br> unaffected and don't affect C++/CLI, unless coincidentally the next token in the macro's<br> definition line happens to be <strong>class</strong> or <strong>struct</strong>; more<br> on this near the end.)</p> <p><strong>3. Contextual keywords that can never appear where an identifier could appear</strong></p> <p>Another technique we used was to define some keywords that can only appear in positions<br> in the language grammar where today nothing may appear. These too are safe: They can't<br> conflict with any user identifiers because no identifiers could appear where the keyword<br> appears, and vice versa. Currently these are:</p> <p>&nbsp; <strong>abstract finally in <br> override sealed where</strong></p> <p>For example, <strong>abstract</strong> as a C++/CLI keyword can only appear in a class<br> definition after the class name and before the base class list, where nothing can<br> appear today:</p> <p>&nbsp; <strong>ref class X abstract : B1, B2 {</strong> // ok, can only be the keyword</p> <p>&nbsp;&nbsp;&nbsp; <strong>int abstract;</strong> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<br> ok, just another identifier</p> <p>&nbsp; <strong>};</strong></p> <p>&nbsp; <strong>class abstract { };</strong> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<br> ok, just another identifier</p> <p>&nbsp; <strong>namespace abstract { /*...*/ }</strong> &nbsp; // ok, just another identifier</p> <p><strong>4. Contextual keywords that can appear where an identifier could appear</strong></p> <p>Some keywords can appear in a grammar position where an identifier could also appear,<br> and this is the case that needs some extra attention. There are currently five keywords<br> in this category:</p> <p>&nbsp; <strong>delegate event initonly <br> literal property</strong></p> <p>In such grammar positions, when the compiler encounters a token that is spelled the<br> same as one of these keywords, the compiler can't know whether the token means the<br> keyword or whether it means an identifier until it first does some further lookahead<br> to consider later tokens. For example, consider the following inside a class scope:</p> <p>&nbsp; <strong>property int x;</strong> &nbsp; // ok, here property is the contextual<br> keyword</p> <p>&nbsp; <strong>property x;</strong> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ok, if property<br> is the name of a type</p> <p>Now imagine you're a compiler: What do you do when you hit the token <strong>property</strong> as<br> the first token of the next class member declaration? There's not enough information<br> to decide for sure whether it's an identifier or a keyword without looking further<br> ahead, and C++/CLI has to specify the decision procedure -- the rules for deciding<br> whether it's a keyword or an identifier. As long as the user doesn't make a mistake<br> (i.e., as long as it's a legal program with or without C++/CLI) the answer is clear,<br> because there's no ambiguity.</p> <p>But now the "quality of diagnostics" issue&nbsp;rears its head, in this category of<br> contextual keywords&nbsp;and this&nbsp;category only: What if the user makes a mistake?<br> For example:</p> <p>&nbsp; <strong>property x;</strong> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // error, if no<br> type "property" exists</p> <p>Let's say that we set up a disambiguation rule with the following general structure<br> (I'll get specific in just a moment):</p> <p>&nbsp; 1. Assume one case and try to parse what comes next that way.</p> <p>&nbsp; 2. If that fails, then assume the other case and try again.</p> <p>&nbsp; 3. If that fails, then issue a diagnostic.</p> <p>In the case of <strong>property x;</strong> when there's no type in scope named <strong>property</strong>,<br> both #1 and #2 will fail and the question is: When we get to the diagnostic in case<br> #3, what error message is the user likely to see? The answer almost certainly is,<br> a message that applies to the second "other" case. Why? Because the compiler already<br> tried the first case, failed, backed up and tried the second "other" case -- and it's<br> still in that latter mode with all that context when it finally realizes that didn't<br> work either and now it has to issue the diagnostic. So by default, absent some (often<br> prodigious) amount of extra work inside the compiler, the diagnostic that you'll get<br> is the one that's easiest to give, namely the one for the case the compiler was most<br> recently pursuing, namely the "other" case mentioned in #2 -- because the compiler<br> already gave up on the first case, and went down the other path instead.</p> <p>So let's get specific. Let's say that the rule we picked was:</p> <p>&nbsp; 1. Assume that it's an identifier and try to parse it that way</p> <p>&nbsp;&nbsp;&nbsp;&nbsp; (i.e., by default assume no use of the keyword extension).</p> <p>&nbsp; 2. If that fails, then assume that it's the keyword and try again.</p> <p>&nbsp; 3. If that fails, then issue a diagnostic.</p> <p>Under that rule, what's the diagnostic the user gets on an illegal declaration of <strong>property<br> x;</strong> ? One that's in the context of #2 (keyword), something like "illegal property<br> declaration," perhaps with a "the type '<strong>x</strong>' was not defined" or a<br> "you forgot to specify the type for property '<strong>x</strong>'" in there somewhere.</p> <p>On the other hand, let's say that the rule we picked was:</p> <p>&nbsp; 1. Assume that it's the keyword and try to parse it that way.</p> <p>&nbsp; 2. If that fails, then assume that it's an identifier and try again.</p> <p>&nbsp; 3. If that fails, then issue a diagnostic.</p> <p>Under this rule, the diagnostic that's easy to give is something like "the type '<strong>property</strong>'<br> was not defined."</p> <p>Which is better?</p> <p>This illustrates why it's very important to consider common mistakes and whether the<br> diagnostic the user will get really applies to what he was probably trying to do.<br> In this case, it's probably better to emit something like "no type named '<strong>property</strong>'<br> exists" than "you forgot to specify a type for your property named '<strong>x</strong>'"<br> -- the former is more likely to address what the user was trying to do, and it also<br> happens to preserve the diagnostics for ISO C++ programs.</p> <p>More broadly, of course, there are other rules you can use than the two "try one way<br> then try the other" variants shown above. But I hope this helps to give the flavor<br> for the 'quality of diagnostics' problem.</p> <p>-<br> Aside: There's usually no&nbsp;ambiguity in the case of <strong>property</strong> (or<br> the other keywords in this category); the only case I know of where you could write<br> legal C++/CLI code where one of these five keywords&nbsp;could be legally interpreted<br> both ways, both as the keyword and as an identifier,&nbsp;is when the type has a global<br> qualification. Here's an&nbsp;example courtesy of Mark Hall:</p> <pre><code>&nbsp;&nbsp;&nbsp;**initonly :: T t;** Is this a declaration of an **initonly** member **t** of type **::T** (i.e, **initonly ::T t;** ),&nbsp;or a declaration of a member **t** of type **initonly::T** (i.e, **initonly::T &lt;br&gt; t;** where if initonly is the name of a namespace or class then this is legal ISO C++). Our current thinking is to adopt the rule "if it can be an identifier, it is," and so this case would mean the latter, either always (even if there's no such type) or perhaps only if there is such a type. </code></pre> <p>I feel compelled to add that the collaboration and input over the past year-plus from <a href="https://www.research.att.com/%7Ebs" data-linktype="external">Bjarne<br> Stroustrup</a> and the folks at <a href="https://www.edg.com" data-linktype="external">EDG</a> (Steve Adamczyk,<br> John Spicer, and Daveed Vandevoorde) has been wonderful and invaluable in this regard<br> specifically. It has really helped to have input from other experienced compiler writers,<br> including in Bjarne's case the creator of the first C++ compiler and in EDG's case<br> the folks who have one of the world's strongest current C++ compilers. On several<br> occasions all of their input has helped get rid of inadvertent assumptions about "what's<br> implementable" and "what's diagnosable" based on just VC++'s own compiler implementation<br> and its source base. What's easy for one compiler implementation is not necessarily<br> so for another, and it's been extremely useful to draw on the experience of comparing<br> notes from two current popular ones to make sure that features can be implemented<br> readily on various compiler architectures and source bases (not just VC++'s) and with<br> quality user diagnostics.</p> <p><strong>5. Not keywords, but in a namespace scope</strong></p> <p>Finally, there are a few "namespaced" keywords. These make the most sense for pseudo-library<br> features (ones that look and feel like library types/functions but really are special<br> names known to the compiler because the compiler does special things when handling<br> them). They appear in the <strong>stdcli</strong> namespace and are:</p> <p>&nbsp; <strong>array interior_ptr pin_ptr <br> safe_cast</strong></p> <p>That's it.</p> <p>Now, for a moment let's go back to case #1, reserved words. Right now we're down to<br> three reserved words. What would it take to get down to zero? Consider the cases:</p> <h2 id="-nullptr-this-has-been-proposed-in-wg21j16-for-c0x-and-at-thelast-meeting-three-weeks-ago-the-evolution-working-group-ewg-was-favorable-to-itbut-wanted-a-few-changes-the-proposal-paper-was-written-by-me-and-bjarne-andwe-will-revise-the-paper-for-thenext-meeting-to-reflect-the-ewg-direction-if-c0x-does-adopt-the-proposal-and-choosesto-take-the-keyword-nullptr-then-the-list-of-ccli-reserved-wordsgoes-down-to-two-and-ccli-would-just-directly-follow-the-c0x-design-for-nullptrincluding-any-changes-c0x-makes-to-it">- <strong>nullptr</strong>: This has been proposed in WG21/J16 for C++0x, and at the last meeting three weeks ago the evolution working group (EWG) was favorable to it but wanted a few changes. The <a href="https://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1488.pdf" data-linktype="external">proposal<br> paper</a> was written by me and Bjarne, and&nbsp;we will revise the paper for the next meeting to reflect the EWG direction. If C++0x does adopt the proposal and chooses to take the keyword <strong>nullptr</strong> then the list of C++/CLI reserved words goes down to two and C++/CLI would just directly follow the C++0x design for nullptr, including any changes C++0x makes to it.</h2> <pre><code>**gcnew**: One obvious way to avoid taking this as a reserved word would be to put it into bucket \#1 as a spaced keyword, "**gc new**". </code></pre> <ul> <li><strong>generic</strong>: Similarly, a spaced keyword (possibly "<strong>generic template</strong>")<br> would avoid taking this reserved word. Unfortunately, spelling it "&lt;anything&gt; <strong>template</strong>"<br> is not only ugly, but seriously misleading because a generic really is not at all<br> a template.</li> </ul> <p>Is it worth it to push all the way down to zero reserved words in C++/CLI? There are<br> pros and cons to doing so, but I've certainly always been sympathetic to the goal<br> of zero reserved words; <a href="https://blogs.gotdotnet.com/branbray" data-linktype="external">Brandon</a> and<br> others will surely tell you of my stubborn campaigning to kill off reserved words<br> (I think I've killed off over a half dozen already since I took the reins of this<br> effort in January, but I haven't kept an exact body count).</p> <p>I think the right time to decide whether to push for zero reserved words is probably<br> near the end of the C++/CLI standards process (summer-ish 2004). At that point, when<br> all other changes and refinements have been made and everything else is in its final<br> form, we will have a complete (and I hope still very short) list of places where C++/CLI<br> could change the meaning of an existing C++ program, and that will be the best time<br> to consider them as a package and to make a decision whether to eliminate some or<br> all of them in a drive-it-to-zero cleanup push. I am looking forward to seeing what<br> the other participants in all C++ standards arenas, and the broader community, think<br> is the right thing to do as we get there.</p> <p>Putting it all together, what's the impact on a legal ISO C++ program? Only:</p> <h2 id="-the-zero-to-three-reserved-words-which-we-may-get-down-to-zero">- The (zero to three) reserved words, which we may get down to zero.</h2> <pre><code>Macros with the same name as a contextual keyword, which ought to be&nbsp;rare because macros with all-lowercase names, never mind names that are common words, are already considered bad form and liable to break way more code than just C++/CLI. (For example, if a macro named **event** existed it would already be breaking most attempts to use Standard C++ iostreams, because the iostreams library has an enum named **event**.) </code></pre> <p>Let me illustrate the macro cases with two main examples that affect the spaced keywords:</p> <p>&nbsp; // Example 1: this has a different meaning in ISO C++ and C++/CLI</p> <p>&nbsp; <strong>#define interface struct</strong></p> <p>In ISO C++, this means change every instance of <strong>interface</strong> to <strong>struct</strong>.<br> In C++/CLI, because "<strong>interface struct</strong>" is a single token, the macro<br> means instead to change every instance of "<strong>interface struct</strong>" to nothing.</p> <p>Here's the simplest workaround:</p> <p>&nbsp; // Workaround 1: this has the same meaning in both</p> <p>&nbsp; <strong>#define interface interface__<br> #define interface__ struct</strong></p> <p>Here's another example of a macro that can change the meaning of a program in ISO<br> C++ and C++/CLI:</p> <p>&nbsp; // Example 2: this has a different meaning in ISO C++ and C++/CLI</p> <p>&nbsp; <strong>#define ref const<br> ref class C { } c;</strong></p> <p>In ISO C++, <strong>ref</strong> goes to <strong>const</strong> and the last line<br> defines a class <strong>C</strong> and simultaneously declares a const object of that<br> type named <strong>c</strong>. This is legal code, albeit uncommon. In C++/CLI, the<br> macro has no effect on the class declaration because "<strong>ref class</strong>"<br> is a single token (whereas the macro is looking for the token <strong>ref</strong>&nbsp;alone,<br> not "<strong>ref class</strong>") and so the last line defines a ref class <strong>C</strong> and<br> simultaneously declares a (non-const) object of that type named <strong>c</strong>.</p> <p>Here's the simplest workaround:</p> <p>&nbsp; // Workaround 2: this has the same meaning in both</p> <p>&nbsp; <strong>#define REF const<br> REF class C { } c;</strong></p> <p>But hey, macro names are supposed to be uppercase anyway. :-)</p> <p>I hope these cases are somewhere between obscure and pathological. At any rate, macros<br> with short and common names are generally unusual in the wild because they just break<br> so much stuff. I would rate example 1 above as fairly obscure (although windows.h<br> has exactly that line in it, alas) and example 2 as probably outright pathological<br> (as I would rate all macros with short and common names).</p> <p>Whew. That's all for tonight.</p> <h2 id="comments">Comments</h2> <ul> <li><strong>Anonymous</strong><br> November 24, 2003<br> I was all set to say, "#define interface struct is not at all obscure - it's in the VC++ header files." So, I guess the next version of the compiler will have new header files defining interface IDispatch, etc?</li> <li><strong>Anonymous</strong><br> November 29, 2003<br> The comment has been removed</li> <li><strong>Anonymous</strong><br> June 09, 2009<br> PingBack from <a href="http://quickdietsite.info/story.php?id=12620" data-linktype="external">http://quickdietsite.info/story.php?id=12620</a></li> </ul> </div><div id="ms--inline-notifications" class="margin-block-xs" data-bi-name="inline-notification"></div><div id="assertive-live-region" role="alert" aria-live="assertive" class="visually-hidden" aria-relevant="additions" aria-atomic="true"></div> <div id="polite-live-region" role="status" aria-live="polite" class="visually-hidden" aria-relevant="additions" aria-atomic="true"></div> <!-- </content> --> </main><!-- recommendations section --><!-- end recommendations section --> <!-- feedback section --><!-- end feedback section --> <!-- feedback report section --><!-- end feedback report section --><aside id="ms--additional-resources-mobile" aria-label="Additional resources" class="display-none-desktop display-none-print" > <hr class="hr" hidden /> <h2 id="ms--additional-resources-mobile-heading" class="title is-3" hidden>Additional resources</h2> <section id="right-rail-recommendations-mobile" data-bi-name="recommendations" hidden></section> <section id="right-rail-training-mobile" data-bi-name="learning-resources-card" hidden></section> <section id="right-rail-events-mobile" data-bi-name="events-card" hidden></section> <section id="right-rail-qna-mobile" data-bi-name="qna-link-card" hidden></section> </aside><div class="border-top is-visible-interactive has-default-focus margin-top-sm "><footer id="footer-interactive" data-bi-name="footer" class="footer-layout"><div class="display-flex gap-xs flex-wrap-wrap is-full-height padding-right-lg-desktop"><a data-mscc-ic="false" class="locale-selector-link button button-sm button-clear flex-shrink-0" href="#" data-bi-name="select-locale"> <span class="icon" aria-hidden="true"> <span class="docon docon-world"></span> </span> <span class="local-selector-link-text"></span></a><div class="ccpa-privacy-link" data-ccpa-privacy-link hidden> <a href="https://aka.ms/yourcaliforniaprivacychoices" class="button button-sm button-clear flex-shrink-0" data-mscc-ic="false" data-bi-name="your-privacy-choices" > <svg role="img" aria-label="California Consumer Privacy Act (CCPA) Opt-Out Icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 14" xml:space="preserve" height="16" width="43" focusable="false" > <title>California Consumer Privacy Act (CCPA) Opt-Out Icon</title> <path d="M7.4 12.8h6.8l3.1-11.6H7.4C4.2 1.2 1.6 3.8 1.6 7s2.6 5.8 5.8 5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#fff"></path> <path d="M22.6 0H7.4c-3.9 0-7 3.1-7 7s3.1 7 7 7h15.2c3.9 0 7-3.1 7-7s-3.2-7-7-7zm-21 7c0-3.2 2.6-5.8 5.8-5.8h9.9l-3.1 11.6H7.4c-3.2 0-5.8-2.6-5.8-5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#06f"></path> <path d="M24.6 4c.2.2.2.6 0 .8L22.5 7l2.2 2.2c.2.2.2.6 0 .8-.2.2-.6.2-.8 0l-2.2-2.2-2.2 2.2c-.2.2-.6.2-.8 0-.2-.2-.2-.6 0-.8L20.8 7l-2.2-2.2c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0l2.2 2.2L23.8 4c.2-.2.6-.2.8 0z" style="fill:#fff"></path> <path d="M12.7 4.1c.2.2.3.6.1.8L8.6 9.8c-.1.1-.2.2-.3.2-.2.1-.5.1-.7-.1L5.4 7.7c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0L8 8.6l3.8-4.5c.2-.2.6-.2.9 0z" style="fill:#06f"></path> </svg> <span>Your Privacy Choices</span> </a> </div> <div class="flex-shrink-0"> <div class="dropdown has-caret-up"> <button class="dropdown-trigger button button-clear button-sm has-inner-focus theme-dropdown-trigger" aria-controls="theme-menu-interactive" aria-expanded="false" title="Theme" data-bi-name="theme"> <span class="icon"> <span class="docon docon-sun" aria-hidden="true"></span> </span> <span>Theme</span> <span class="icon expanded-indicator" aria-hidden="true"> <span class="docon docon-chevron-down-light"></span> </span> </button> <div class="dropdown-menu" id="theme-menu-interactive" role="menu"> <ul class="theme-selector padding-xxs" role="none"> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="light"> <span class="theme-light margin-right-xxs"> <span class="theme-selector-icon border display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Light</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="dark"> <span class="theme-dark margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Dark</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="high-contrast"> <span class="theme-high-contrast margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>High contrast</span> </button> </li> </ul> </div> </div> </div> </div> <ul class="links" data-bi-name="footerlinks"> <li class="manage-cookies-holder" hidden></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/previous-versions/" data-bi-name="archivelink">Previous Versions</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="https://techcommunity.microsoft.com/t5/microsoft-learn-blog/bg-p/MicrosoftLearnBlog" data-bi-name="bloglink">Blog</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/contribute/" data-bi-name="contributorGuide">Contribute</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://go.microsoft.com/fwlink/?LinkId=521839" data-bi-name="privacy">Privacy</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/legal/termsofuse" data-bi-name="termsofuse">Terms of Use</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://www.microsoft.com/legal/intellectualproperty/Trademarks/" data-bi-name="trademarks">Trademarks</a></li><li>&copy; Microsoft 2024</li> </ul> </footer></div></div><div id="ms--additional-resources" class="right-container column is-4-desktop display-none display-block-desktop" data-bi-name="pageactions" role="complementary" aria-label="Additional resources" > <div id="affixed-right-container" class="margin-top-sm-tablet" data-bi-name="right-column"> <h2 id="ms--additional-resources-heading" class="title is-6 margin-top-md" hidden>Additional resources</h2> <section id="right-rail-events" data-bi-name="events-card" hidden></section> <section id="right-rail-training" data-bi-name="learning-resources-card" hidden></section> <section id="right-rail-recommendations" data-bi-name="recommendations" hidden></section> <nav id="side-doc-outline" class="doc-outline" data-bi-name="intopic toc" aria-label="In this article"> <h3>In this article</h3> </nav> <section id="right-rail-qna" class="margin-top-xxs" data-bi-name="qna-link-card" hidden></section> </div> </div></div> <!--end of div.columns --> </section> <!--end of .primary-holder --> <!-- interactive container --> <aside id="interactive-container" class="interactive-container is-visible-interactive column has-body-background-dark "> </aside> <!-- end of interactive container --> </div> </div> <!--end of .mainContainer --> <section class="border-top has-default-focus is-hidden-interactive margin-top-sm "><footer id="footer" data-bi-name="footer" class="footer-layout uhf-container has-padding" role="contentinfo"><div class="display-flex gap-xs flex-wrap-wrap is-full-height padding-right-lg-desktop"><a data-mscc-ic="false" class="locale-selector-link button button-sm button-clear flex-shrink-0" href="#" data-bi-name="select-locale"> <span class="icon" aria-hidden="true"> <span class="docon docon-world"></span> </span> <span class="local-selector-link-text"></span></a><div class="ccpa-privacy-link" data-ccpa-privacy-link hidden> <a href="https://aka.ms/yourcaliforniaprivacychoices" class="button button-sm button-clear flex-shrink-0" data-mscc-ic="false" data-bi-name="your-privacy-choices" > <svg role="img" aria-label="California Consumer Privacy Act (CCPA) Opt-Out Icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 14" xml:space="preserve" height="16" width="43" focusable="false" > <title>California Consumer Privacy Act (CCPA) Opt-Out Icon</title> <path d="M7.4 12.8h6.8l3.1-11.6H7.4C4.2 1.2 1.6 3.8 1.6 7s2.6 5.8 5.8 5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#fff"></path> <path d="M22.6 0H7.4c-3.9 0-7 3.1-7 7s3.1 7 7 7h15.2c3.9 0 7-3.1 7-7s-3.2-7-7-7zm-21 7c0-3.2 2.6-5.8 5.8-5.8h9.9l-3.1 11.6H7.4c-3.2 0-5.8-2.6-5.8-5.8z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#06f"></path> <path d="M24.6 4c.2.2.2.6 0 .8L22.5 7l2.2 2.2c.2.2.2.6 0 .8-.2.2-.6.2-.8 0l-2.2-2.2-2.2 2.2c-.2.2-.6.2-.8 0-.2-.2-.2-.6 0-.8L20.8 7l-2.2-2.2c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0l2.2 2.2L23.8 4c.2-.2.6-.2.8 0z" style="fill:#fff"></path> <path d="M12.7 4.1c.2.2.3.6.1.8L8.6 9.8c-.1.1-.2.2-.3.2-.2.1-.5.1-.7-.1L5.4 7.7c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0L8 8.6l3.8-4.5c.2-.2.6-.2.9 0z" style="fill:#06f"></path> </svg> <span>Your Privacy Choices</span> </a> </div> <div class="flex-shrink-0"> <div class="dropdown has-caret-up"> <button class="dropdown-trigger button button-clear button-sm has-inner-focus theme-dropdown-trigger" aria-controls="theme-menu" aria-expanded="false" title="Theme" data-bi-name="theme"> <span class="icon"> <span class="docon docon-sun" aria-hidden="true"></span> </span> <span>Theme</span> <span class="icon expanded-indicator" aria-hidden="true"> <span class="docon docon-chevron-down-light"></span> </span> </button> <div class="dropdown-menu" id="theme-menu" role="menu"> <ul class="theme-selector padding-xxs" role="none"> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="light"> <span class="theme-light margin-right-xxs"> <span class="theme-selector-icon border display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Light</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="dark"> <span class="theme-dark margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>Dark</span> </button> </li> <li class="theme display-block" role="menuitem"> <button class="button button-clear button-sm theme-control button-block justify-content-flex-start" data-theme-to="high-contrast"> <span class="theme-high-contrast margin-right-xxs"> <span class="border theme-selector-icon display-inline-block has-body-background" aria-hidden="true"> <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 14"> <rect width="22" height="14" class="has-fill-body-background" /> <rect x="5" y="5" width="12" height="4" class="has-fill-secondary" /> <rect x="5" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="8" y="2" width="2" height="1" class="has-fill-secondary" /> <rect x="11" y="2" width="3" height="1" class="has-fill-secondary" /> <rect x="1" y="1" width="2" height="2" class="has-fill-secondary" /> <rect x="5" y="10" width="7" height="2" rx="0.3" class="has-fill-primary" /> <rect x="19" y="1" width="2" height="2" rx="1" class="has-fill-secondary" /> </svg> </span> </span> <span>High contrast</span> </button> </li> </ul> </div> </div> </div> </div> <ul class="links" data-bi-name="footerlinks"> <li class="manage-cookies-holder" hidden></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/previous-versions/" data-bi-name="archivelink">Previous Versions</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="https://techcommunity.microsoft.com/t5/microsoft-learn-blog/bg-p/MicrosoftLearnBlog" data-bi-name="bloglink">Blog</a></li> <li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/contribute/" data-bi-name="contributorGuide">Contribute</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://go.microsoft.com/fwlink/?LinkId=521839" data-bi-name="privacy">Privacy</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="/en-us/legal/termsofuse" data-bi-name="termsofuse">Terms of Use</a></li><li><a class="external-link-indicator" data-mscc-ic="false" href="https://www.microsoft.com/legal/intellectualproperty/Trademarks/" data-bi-name="trademarks">Trademarks</a></li><li>&copy; Microsoft 2024</li> </ul> </footer> </section> <div id="action-panel" role="region" aria-label="Action Panel" class="action-panel has-default-focus" tabindex="-1"></div> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10