<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="author" content="Alex Gilding (Perforce UK)" />
  <meta name="author" content="Jens Gustedt (INRIA France)" />
  <meta name="dcterms.date" content="2022-04-08" />
  <title>Type inference for object definitions</title>
  <style type="text/css">
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>
  <style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
  { content: attr(title);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    background-color: #ffffff;
    color: #a0a0a0;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #a0a0a0;  padding-left: 4px; }
div.sourceCode
  { color: #1f1c1b; background-color: #ffffff; }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span. { color: #1f1c1b; } /* Normal */
code span.al { color: #bf0303; background-color: #f7e6e6; font-weight: bold; } /* Alert */
code span.an { color: #ca60ca; } /* Annotation */
code span.at { color: #0057ae; } /* Attribute */
code span.bn { color: #b08000; } /* BaseN */
code span.bu { color: #644a9b; font-weight: bold; } /* BuiltIn */
code span.cf { color: #1f1c1b; font-weight: bold; } /* ControlFlow */
code span.ch { color: #924c9d; } /* Char */
code span.cn { color: #aa5500; } /* Constant */
code span.co { color: #898887; } /* Comment */
code span.cv { color: #0095ff; } /* CommentVar */
code span.do { color: #607880; } /* Documentation */
code span.dt { color: #0057ae; } /* DataType */
code span.dv { color: #b08000; } /* DecVal */
code span.er { color: #bf0303; text-decoration: underline; } /* Error */
code span.ex { color: #0095ff; font-weight: bold; } /* Extension */
code span.fl { color: #b08000; } /* Float */
code span.fu { color: #644a9b; } /* Function */
code span.im { color: #ff5500; } /* Import */
code span.in { color: #b08000; } /* Information */
code span.kw { color: #1f1c1b; font-weight: bold; } /* Keyword */
code span.op { color: #1f1c1b; } /* Operator */
code span.ot { color: #006e28; } /* Other */
code span.pp { color: #006e28; } /* Preprocessor */
code span.re { color: #0057ae; background-color: #e0e9f8; } /* RegionMarker */
code span.sc { color: #3daee9; } /* SpecialChar */
code span.ss { color: #ff5500; } /* SpecialString */
code span.st { color: #bf0303; } /* String */
code span.va { color: #0057ae; } /* Variable */
code span.vs { color: #bf0303; } /* VerbatimString */
code span.wa { color: #bf0303; } /* Warning */
  </style>
  <!-- (A) TOGGLE PROPERTY WITH JAVASCRIPT -->
  <script>
  function hideDel () {
      var block = document.getElementsByTagName("del");
      let fLen = block.length;
      for (let i = 0; i < fLen; i++) {
          block[i].style.display = "none";
      }
  }
  function hideIns () {
      var block = document.getElementsByTagName("ins");
      let fLen = block.length;
      for (let i = 0; i < fLen; i++) {
          block[i].style.display = "none";
      }
  }
  function showDel () {
      var block = document.getElementsByTagName("del");
      let fLen = block.length;
      for (let i = 0; i < fLen; i++) {
          block[i].style.display = "";
      }
  }
  function showIns () {
      var block = document.getElementsByTagName("ins");
      let fLen = block.length;
      for (let i = 0; i < fLen; i++) {
          block[i].style.display = "";
      }
  }
  function showOrig () {
      hideIns();
      showDel();
  }
  function showNew () {
      showIns();
      hideDel();
  }
  function showBoth () {
      showIns();
      showDel();
  }
  function toggleToc () {
      var block = document.getElementById("TOC");
      let fLen = block.length;
      if (block.style.display == "") {
          block.style.display = "none";
      } else {
          block.style.display = "";
      }
  }
  </script>
  <!-- (B) TEST BLOCK OF TEXT -->
  <table id="diffToggles" style="position: fixed; top: 0; right: 0; z-index: 1"/>
  <tbody>
  <tr><td><input type="button" value="toggle toc" onclick="toggleToc()"/></td><tr>
  <tr><td><input type="button" value="show orig" onclick="showOrig()"/></td><tr>
  <tr><td><input type="button" value="show new" onclick="showNew()"/></td><tr>
  <tr><td><input type="button" value="show both" onclick="showBoth()"/></td><tr>
  </tbody>
  </table>
  <style>
    /*
      Buttondown
      A Markdown/MultiMarkdown/Pandoc HTML output CSS stylesheet
      Author: Ryan Gray
      Date: 15 Feb 2011
      Revised: 21 Feb 2012
     
      General style is clean, with minimal re-definition of the defaults or 
      overrides of user font settings. The body text and header styles are 
      left alone except title, author and date classes are centered. A Pandoc TOC 
      is not printed, URLs are printed after hyperlinks in parentheses. 
      Block quotes are italicized. Tables are lightly styled with lines above 
      and below the table and below the header with a boldface header. Code 
      blocks are line wrapped. 
  
      All elements that Pandoc and MultiMarkdown use should be listed here, even 
      if the style is empty so you can easily add styling to anything.
      
      There are some elements in here for HTML5 output of Pandoc, but I have not 
      gotten around to testing that yet.
  */
  
  /* NOTES:
  
      Stuff tried and failed:
      
      It seems that specifying font-family:serif in Safari will always use 
      Times New Roman rather than the user's preferences setting.
      
      Making the font size different or a fixed value for print in case the screen 
      font size is making the print font too big: Making font-size different for 
      print than for screen causes horizontal lines to disappear in math when using 
      MathJax under Safari.
  */
  
  /* ---- Front Matter ---- */
  
  /* Pandoc header DIV. Contains .title, .author and .date. Comes before div#TOC. 
     Only appears if one of those three are in the document.
  */
  
  body {counter-reset: h2}
    h2 {counter-reset: h3}
    h2 {counter-reset: h3}
    h3 {counter-reset: h4}
    h4 {counter-reset: h5}
    h5 {counter-reset: h6}
  
    h2:before {counter-increment: h2; content: counter(h2) ". "}
    h3:before {counter-increment: h3; content: counter(h2) "." counter(h3) ". "}
    h4:before {counter-increment: h4; content: counter(h2) "." counter(h3) "." counter(h4) ". "}
    h5:before {counter-increment: h5; content: counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "}
    h6:before {counter-increment: h6; content: counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "}
  
    h2.nocount:before, h3.nocount:before, h4.nocount:before, h5.nocount:before, h6.nocount:before { content: ""; counter-increment: none }
    
  div#header, header
      {
      /* Put border on bottom. Separates it from TOC or body that comes after it. */
      border-bottom: 1px solid #aaa;
      margin-bottom: 0.5em;
      }
  
  .title /* Pandoc title header (h1.title) */
      {
      text-align: center;
      }
  
  .author, .date /* Pandoc author(s) and date headers (h2.author and h3.date) */
  {
      font-size: 3ex;
      text-align: center;
      }
  
  /* Pandoc table of contents DIV when using the --toc option.
     NOTE: this doesn't support Pandoc's --id-prefix option for #TOC and #header. 
     Probably would need to use div[id$='TOC'] and div[id$='header'] as selectors.
  */
  
  div#TOC, nav#TOC
      {
      /* Put border on bottom to separate it from body. */
      border-bottom: 1px solid #aaa;
      margin-bottom: 0.5em;
      }
  
  ins {
      color: green
  }
  
  del {
      color: red
  }
  
  #diffToggles {
      display: none
  }
  
  @media screen
  {
      #TOC
      {
          width: 35%;
  	float: left;
  	overflow: hidden;
      }
      #diffToggles {
          display: block
      }
  }
  
  @media print
      {
      div#TOC, nav#TOC
          {
          /* Don't display TOC in print */
          display: none;
          }
      }
  
  /* ---- Headers and sections ---- */
  
  h1, h2, h3, h4, h5, h6
  {
      font-family: "Helvetica Neue", Helvetica, "Liberation Sans", Calibri, Arial, sans-serif; /* Sans-serif headers */
  
      /* font-family: "Liberation Serif", "Georgia", "Times New Roman", serif; /* Serif headers */
  
      page-break-after: avoid; /* Firefox, Chrome, and Safari do not support the property value "avoid" */
  }
  
  /* Pandoc with --section-divs option */
  
  div div, section section /* Nested sections */
      {
      margin-left: 2em; /* This will increasingly indent nested header sections */
      }
  
  p {}
  
  blockquote
      { 
      font-style: italic;
      }
  
  li /* All list items */
      {
      }
  
  li > p /* Loosely spaced list item */
      {
      margin-top: 1em; /* IE: lack of space above a <li> when the item is inside a <p> */
      }
  
  ul /* Whole unordered list */
      {
      }
  
  ul li /* Unordered list item */
      {
      }
  
  ol /* Whole ordered list */
      {
      }
  
  ol li /* Ordered list item */
      {
      }
  
  hr {}
  
  /* ---- Some span elements --- */
  
  sub /* Subscripts. Pandoc: H~2~O */
      {
      }
  
  sup /* Superscripts. Pandoc: The 2^nd^ try. */
      {
      }
      
  em /* Emphasis. Markdown: *emphasis* or _emphasis_ */
      {
      }
      
  em > em /* Emphasis within emphasis: *This is all *emphasized* except that* */
      {
      font-style: normal;
      }
  
  blockquote > p > em /* Emphasis within emphasis: *This is all *emphasized* except that* */
      {
      font-style: normal;
      }
  
  blockquote > * > p > em /* Emphasis within emphasis: *This is all *emphasized* except that* */
      {
      font-style: normal;
      }
  
  blockquote > p > ins > em /* Emphasis within emphasis: *This is all *emphasized* except that* */
      {
      font-style: normal;
      }
  
  blockquote > * > p > ins > em /* Emphasis within emphasis: *This is all *emphasized* except that* */
      {
      font-style: normal;
      }
  
  /* ---- Links (anchors) ---- */
  
  a /* All links */
      {
      /* Keep links clean. On screen, they are colored; in print, they do nothing anyway. */
      text-decoration: none;
      }
  
  @media screen
      {
      a:hover
          {
          /* On hover, we indicate a bit more that it is a link. */
          text-decoration: underline;
          }
      }
  
  @media print
      {
      a   {
          /* In print, a colored link is useless, so un-style it. */
          color: black;
          background: transparent;
          }
          
      a[href^="http://"]:after, a[href^="https://"]:after
          {
          /* However, links that go somewhere else, might be useful to the reader,
             so for http and https links, print the URL after what was the link 
             text in parens
          */
          content: " (" attr(href) ") ";
          font-size: 90%;
          }
      }
  
  /* ---- Images ---- */
  
  img
      {
      /* Let it be inline left/right where it wants to be, but verticality make 
         it in the middle to look nicer, but opinions differ, and if in a multi-line 
         paragraph, it might not be so great. 
      */
      vertical-align: middle;
      }
  
  div.figure /* Pandoc figure-style image */
      {
      /* Center the image and caption */
      margin-left: auto;
      margin-right: auto;
      text-align: center;
      font-style: italic;
      }
  
  p.caption /* Pandoc figure-style caption within div.figure */
      {
      /* Inherits div.figure props by default */
      }
  
  /* ---- Code blocks and spans ---- */
  
  pre, code 
      {
      background-color: #fdf7ee;
      /* BEGIN word wrap */
      /* Need all the following to word wrap instead of scroll box */
      /* This will override the overflow:auto if present */
      white-space: pre-wrap; /* css-3 */
      white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
      white-space: -pre-wrap; /* Opera 4-6 */
      white-space: -o-pre-wrap; /* Opera 7 */
      word-wrap: break-word; /* Internet Explorer 5.5+ */
      /* END word wrap */
      }
  
  pre /* Code blocks */
      {
      /* Distinguish pre blocks from other text by more than the font with a background tint. */
      padding: 0.5em; /* Since we have a background color */
      border-radius: 5px; /* Softens it */
      /* Give it a some definition */
      border: 1px solid #aaa;
      /* Set it off left and right, seems to look a bit nicer when we have a background */
      margin-left:  0.5em;
      margin-right: 0.5em;
      }
  
  @media screen
      {
      pre
          {
          /* On screen, use an auto scroll box for long lines, unless word-wrap is enabled */
          white-space: pre;
          overflow: auto;
          /* Dotted looks better on screen and solid seems to print better. */
          border: 1px dotted #777;
          }
      }
  
  code /* All inline code spans */
      {
      }
  
  p > code, li > code /* Code spans in paragraphs and tight lists */
      {
      /* Pad a little from adjacent text */
      padding-left:  2px;
      padding-right: 2px;
      }
      
  li > p code /* Code span in a loose list */
      {
      /* We have room for some more background color above and below */
      padding: 2px;
      }
  
  span.option
      {
          color: blue;
          text-decoration: underline;
      }
  
  
  /* ---- Math ---- */
  
  span.math /* Pandoc inline math default and --jsmath inline math */
      {
      /* Tried font-style:italic here, and it messed up MathJax rendering in some browsers. Maybe don't mess with at all. */
      }
      
  div.math /* Pandoc --jsmath display math */
      {
      }
      
  span.LaTeX /* Pandoc --latexmathml math */
      {
      } 
  
  eq /* Pandoc --gladtex math */
      {
      } 
  
  /* ---- Tables ---- */
  
  /*  A clean textbook-like style with horizontal lines above and below and under 
      the header. Rows highlight on hover to help scanning the table on screen.
  */
  
  table
      {
      border-collapse: collapse;
      border-spacing: 0; /* IE 6 */
  
      border-bottom: 2pt solid #000;
      border-top: 2pt solid #000; /* The caption on top will not have a bottom-border */
  
      /* Center */
      margin-left: auto;
      margin-right: auto;
      }
      
  thead /* Entire table header */
      {
      border-bottom: 1pt solid #000;
      background-color: #eee; /* Does this BG print well? */
      }
  
  tr.header /* Each header row */
      {
      } 
  
  tbody /* Entire table  body */
      {
      }
  
  /* Table body rows */
  
  tr  {
      }
  tr.odd:hover, tr.even:hover /* Use .odd and .even classes to avoid styling rows in other tables */
      {
      background-color: #eee;
      }
      
  /* Odd and even rows */
  tr.odd {}
  tr.even {}
  
  td, th /* Table cells and table header cells */
      { 
      vertical-align: top; /* Word */
      vertical-align: baseline; /* Others */
      padding-left:   0.5em;
      padding-right:  0.5em;
      padding-top:    0.2em;
      padding-bottom: 0.2em;
      }
      
  /* Removes padding on left and right of table for a tight look. Good if thead has no background color*/
  /*
  tr td:last-child, tr th:last-child
      {
      padding-right: 0;
      }
  tr td:first-child, tr th:first-child 
      {
      padding-left: 0;
      }
  */
  
  th /* Table header cells */
      {
      font-weight: bold; 
      }
  
  tfoot /* Table footer (what appears here if caption is on top?) */
      {
      }
  
  caption /* This is for a table caption tag, not the p.caption Pandoc uses in a div.figure */
      {
      caption-side: top;
      border: none;
      font-size: 0.9em;
      font-style: italic;
      text-align: center;
      margin-bottom: 0.3em; /* Good for when on top */
      padding-bottom: 0.2em;
      }
  
  /* ---- Definition lists ---- */
  
  dl /* The whole list */
      {
      border-top: 2pt solid black;
      padding-top: 0.5em;
      border-bottom: 2pt solid black;
      }
  
  dt /* Definition term */
      {
      font-weight: bold;
      }
  
  dd+dt /* 2nd or greater term in the list */
      {
      border-top: 1pt solid black;
      padding-top: 0.5em;
      }
      
  dd /* A definition */
      {
      margin-bottom: 0.5em;
      }
  
  dd+dd /* 2nd or greater definition of a term */
      {
      border-top: 1px solid black; /* To separate multiple definitions */
      }
      
  /* ---- Footnotes ---- */
  
  a.footnote, a.footnoteRef { /* Pandoc, MultiMarkdown footnote links */
      font-size: small; 
      vertical-align: text-top;
  }
  
  a[href^="#fnref"], a.reversefootnote /* Pandoc, MultiMarkdown, ?? footnote back links */
      {
      }
  
  @media print
      {
      a[href^="#fnref"], a.reversefootnote /* Pandoc, MultiMarkdown */
          {
          /* Don't display these at all in print since the arrow is only something to click on */
          display: none;
          }
      }
      
  div.footnotes /* Pandoc footnotes div at end of the document */
      {
      }
      
  div.footnotes li[id^="fn"] /* A footnote item within that div */
      {
      }
  
  /* You can class stuff as "noprint" to not print. 
     Useful since you can't set this media conditional inside an HTML element's 
     style attribute (I think), and you don't want to make another stylesheet that 
     imports this one and adds a class just to do this.
  */
  
  @media print
      {
      .noprint
          {
          display:none;
          }
      }
  
  </style>
</head>
<body>
<header id="title-block-header">
<h1 class="title">Type inference for object definitions</h1>
<p class="author">Alex Gilding (Perforce UK)</p>
<p class="author">Jens Gustedt (INRIA France)</p>
<p class="date">2022-04-08</p>
</header>
<nav id="TOC">
<ul>
<li><a href="#abstract">Abstract</a></li>
<li><a href="#summary-of-changes">Summary of Changes</a></li>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#rationale">Rationale</a></li>
<li><a href="#proposal">Proposal</a><ul>
<li><a href="#alternative-keywords">Alternative keywords</a></li>
<li><a href="#direct-coding-instead-of-the-__auto_type-feature">Direct coding instead of the <code>__auto_type</code> feature</a></li>
</ul></li>
<li><a href="#impact">Impact</a><ul>
<li><a href="#bit-fields">Bit-fields</a></li>
<li><a href="#combined-definitions-and-compatible-types">Combined definitions and compatible types</a></li>
<li><a href="#combined-definitions-and-variably-modified-types">Combined definitions and variably modified types</a></li>
<li><a href="#specifiers">Specifiers</a></li>
<li><a href="#scope">Scope</a></li>
<li><a href="#ambiguities-with-type-definitions">Ambiguities with type definitions</a></li>
</ul></li>
<li><a href="#implementation-experience">Implementation Experience</a></li>
<li><a href="#proposed-wording">Proposed wording</a><ul>
<li><a href="#linkage-of-identifiers-6.2.2">Linkage of identifiers (6.2.2)</a></li>
<li><a href="#keywords-6.4.1">Keywords (6.4.1)</a></li>
<li><a href="#storage-class-specifiers-6.7.1">Storage-class specifiers (6.7.1)</a></li>
<li><a href="#type-specifiers-6.7.2">Type specifiers (6.7.2)</a></li>
<li><a href="#type-definitions-6.7.8">Type definitions (6.7.8)</a></li>
<li><a href="#declarations-6.7">Declarations (6.7)</a></li>
<li><a href="#non-normative-additions">Non-normative additions</a></li>
</ul></li>
<li><a href="#questions-to-wg14">Questions to WG14</a><ul>
<li><a href="#keyword">Keyword</a></li>
<li><a href="#acceptance">Acceptance</a></li>
</ul></li>
<li><a href="#references">References</a></li>
</ul>
</nav>
<table>
<tbody>
<tr class="odd">
<td style="text-align: left;">org:</td>
<td style="text-align: left;">ISO/IEC JCT1/SC22/WG14</td>
<td>document:</td>
<td>N2953</td>
<td></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">… WG21 C and C++ liaison</td>
<td></td>
<td>P2305</td>
<td></td>
</tr>
<tr class="odd">
<td style="text-align: left;">target:</td>
<td style="text-align: left;">IS 9899:2023</td>
<td>version:</td>
<td>7</td>
<td></td>
</tr>
<tr class="even">
<td style="text-align: left;">date:</td>
<td style="text-align: left;">2022-04-08</td>
<td>license:</td>
<td><a href="https://creativecommons.org/licenses/by/4.0/" title="Distributed under a Creative Commons Attribution 4.0 International License">CC BY</a></td>
<td></td>
</tr>
</tbody>
</table>
<hr />
<h3 id="abstract">Abstract</h3>
<p>We propose the inclusion of the so-called <code>auto</code> feature for variable definitions into C. This feature allows declarations to infer types from the expressions that are used as their initializers. This is part of a series of papers for the improvement of type-generic programming in C that has been introduced in N2890 and is continued with a series of papers that only concern object definitions N2952.</p>
<h3 id="summary-of-changes">Summary of Changes</h3>
<ul>
<li>N2953 (v7/R6)
<ul>
<li>remove type inference for function return types and function parameters</li>
<li>refocus type inference for objects to exactly match existing C practice</li>
<li>avoid type ambiguities by restricting to a single declarator per declaration</li>
</ul></li>
<li>N2923 (v6/R5)
<ul>
<li>move handling of <code>auto</code> parameters to N2924</li>
<li>make type declarations in underspecified declarations undefined behaviour</li>
<li>add Joseph Myers’s wording for the typeof specifier, but make it its own sub-phrase</li>
<li>address an ambiguity concerning the scope of <code>auto</code> variables</li>
<li>make clear that shadowing by <code>auto</code> only concerns ordinary identifiers</li>
<li>minor text adaptions</li>
</ul></li>
<li>N2891 (v5/R4)
<ul>
<li>straighten the proposed text and move discussion of all special cases (bit-fields, compatible types, VM) into non-normative text such as notes and examples</li>
</ul></li>
<li>N2735 (v4/R3)
<ul>
<li>some word smithing</li>
</ul></li>
<li>N2697 (v3/R2)
<ul>
<li>remove a requirement on qualifiers and atomic derivation that was too restrictive</li>
</ul></li>
<li>N2674 (v2/R1)
<ul>
<li>changes the rules for type inference to use a typeof specifier. This simplifies the rules and brings the defined semantics in line with C++.</li>
</ul></li>
<li>N2632
<ul>
<li>original proposal</li>
</ul></li>
</ul>
<h2 id="introduction">Introduction</h2>
<p>Defining a variable in C requires the user to name a type. However when the definition includes an initializer, it makes sense to derive this type directly from the type of the expression used to initialize the variable. This feature has existed in C++ since C++11, and is implemented in GCC, Clang, and other GNU C compatible compilers using the <code>__auto_type</code> extension keyword. <code>__auto_type</code> is a much more limited feature than C++ <code>auto</code>, the latter of which is built on top of template type deduction rules. We propose to standardize the existing C extension practice directly. Any valid C construct using this syntax will also be valid and hold the same meaning within the broader semantics of the C++ feature.</p>
<p>This paper is based on N2952 which lays the ground work for the common syntax terminology that is needed for this paper here (N2953) and for a paper <code>constexpr</code> on object definitions (N2954).</p>
<h2 id="rationale">Rationale</h2>
<p>In N2890 it is argued that the features presented in this paper are useful in a more general context, namely for the combination with lambdas. We will not repeat this argumentation here, but try to motivate the introduction of the <code>auto</code> feature as a stand-alone addition to C. In accordance with C’s syntax for declarations and in extension of its semantics, C++ has a feature that allows to infer the type of a variable from its initializer expression.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">auto</span> y <span class="op">=</span> cos<span class="op">(</span>x<span class="op">);</span></a></code></pre></div>
<p>This eases the use of type-generic functions because now the return value and type can be captured in an auxiliary variable, without necessarily having the type of the argument, here <code>x</code>, at hand. That feature is not only interesting because of the obvious convenience for programmers who are perhaps too lazy to lookup the type of <code>x</code>. It can help to avoid code maintenance problems: if <code>x</code> is a function parameter for which potentially the type may be adjusted during the lifecycle of the program (say from <code>float</code> to <code>double</code>), all dependent auxiliary variables within the function are automatically updated to the new type.</p>
<p>This can even be used if the return type of a type-generic function is just an aggregation of several values for which the type itself is just an uninteresting artefact:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb2-1" title="1"><span class="pp">#define div(X, Y)            \</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="pp">  _Generix((X)+(Y),          \</span></a>
<a class="sourceLine" id="cb2-3" title="3"><span class="pp">           int: div,         \</span></a>
<a class="sourceLine" id="cb2-4" title="4"><span class="pp">           long: ldiv,       \</span></a>
<a class="sourceLine" id="cb2-5" title="5"><span class="pp">           long long: lldiv) \</span></a>
<a class="sourceLine" id="cb2-6" title="6"><span class="pp">           ((X), (Y))</span></a>
<a class="sourceLine" id="cb2-7" title="7"></a>
<a class="sourceLine" id="cb2-8" title="8">  <span class="co">// int, long or long long?</span></a>
<a class="sourceLine" id="cb2-9" title="9">  <span class="kw">auto</span> res <span class="op">=</span> div<span class="op">(</span><span class="dv">38484848448</span><span class="op">,</span> <span class="dv">448484844</span><span class="op">);</span></a>
<a class="sourceLine" id="cb2-10" title="10">  <span class="kw">auto</span> a <span class="op">=</span> b <span class="op">*</span> res<span class="op">.</span>quot <span class="op">+</span> res<span class="op">.</span>rem<span class="op">;</span></a></code></pre></div>
<p>An important restriction for the coding of type-generic macros in current C is the impossibility to declare local variables of a type that is dependent on the type(s) of the macro argument(s). Therefore, such macros often need arguments that provide the types for which the macro was evaluated. This not only inconvenient for the user of such macros but also an important source of errors. If the user chooses the wrong type, implicit conversions can impede on the correctness of the macro call.</p>
<p>For type-generic macros that declare local variables, <code>auto</code> can easily remove the need for the specification of the base types of the macro arguments:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb3-1" title="1"><span class="pp">#define dataCondStoreTG(P, E, D)             \</span></a>
<a class="sourceLine" id="cb3-2" title="2"><span class="pp">  do {                                       \</span></a>
<a class="sourceLine" id="cb3-3" title="3"><span class="pp">    auto* _pr_p = (P);                       \</span></a>
<a class="sourceLine" id="cb3-4" title="4"><span class="pp">    auto _pr_expected = (E);                 \</span></a>
<a class="sourceLine" id="cb3-5" title="5"><span class="pp">    auto _pr_desired = (D);                  \</span></a>
<a class="sourceLine" id="cb3-6" title="6"><span class="pp">    bool _pr_c;                              \</span></a>
<a class="sourceLine" id="cb3-7" title="7"><span class="pp">    do {                                     \</span></a>
<a class="sourceLine" id="cb3-8" title="8"><span class="pp">      mtx_lock(&amp;_pr_p-&gt;mtx);                 \</span></a>
<a class="sourceLine" id="cb3-9" title="9"><span class="pp">      _pr_c = (_pr_p-&gt;data == _pr_expected); \</span></a>
<a class="sourceLine" id="cb3-10" title="10"><span class="pp">      if (_pr_c) _pr_p-&gt;data = _pr_desired;  \</span></a>
<a class="sourceLine" id="cb3-11" title="11"><span class="pp">      mtx_unlock(&amp;_pr_p-&gt;mtx);               \</span></a>
<a class="sourceLine" id="cb3-12" title="12"><span class="pp">    }  while(!_pr_c);                        \</span></a>
<a class="sourceLine" id="cb3-13" title="13"><span class="pp">  } while (false)</span></a></code></pre></div>
<p>Cs declaration syntax currently already allows to omit the type in a variable definition, as long as the variable is initialized and a storage-class specifier (such as <code>auto</code> or <code>static</code>) disambiguates the construct from an assignment. In previous versions of C the interpretation of such a definition had been <code>int</code>; since C11 this is a constraint violation. We will propose to partially align C with C++, here, and to change this such that the type of the variable is inferred from the type of the initializer expression.</p>
<p>We achieve this by standardizing the existing practice in the GNU C dialect provided by the <code>__auto_type</code> specifier exactly. This is a strict subset of allowed C++11 behaviour. We expect and hope that implementers will treat incompatibilities with extended C++ declaration syntax (such as <code>auto const *</code>) as QoI bugs and implement these as extensions, establishing practice and experience for the C-side interpretation of such declarations. Standardizing the base value-only feature is a necessary basis to allow implementations to build beyond it with extended declarations.</p>
<h2 id="proposal">Proposal</h2>
<p>We propose standardizing the GNU C feature exactly, except for possibly changing the use of the extended specifier <code>__auto_type</code> to the existing specifier <code>auto</code>. The GNU C feature (since version 11) has clear semantics which can be expressed entirely in terms of the adopted typeof feature: the inferred type for a given initializer <code>(init)</code> is, exactly, <code>typeof((0, init))</code>. Namely the type is the type of the expression after lvalue, array-to-pointer or function-to-pointer conversion. Possible qualifiers in case <code>init</code> is an lvalue with a qualified type are dropped by that mechanism.</p>
<p>For example:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb4-1" title="1"><span class="kw">void</span> foo <span class="op">(</span><span class="kw">int</span> x<span class="op">,</span> <span class="kw">int</span> <span class="kw">const</span> y<span class="op">)</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb4-2" title="2">    <span class="kw">__auto_type</span> a <span class="op">=</span> x<span class="op">;</span></a>
<a class="sourceLine" id="cb4-3" title="3">    <span class="kw">__auto_type</span> b <span class="op">=</span> y<span class="op">;</span></a>
<a class="sourceLine" id="cb4-4" title="4">    <span class="kw">int</span> <span class="op">*</span> c <span class="op">=</span> <span class="op">&amp;</span>a<span class="op">;</span></a>
<a class="sourceLine" id="cb4-5" title="5">    <span class="kw">int</span> <span class="op">*</span> d <span class="op">=</span> <span class="op">&amp;</span>b<span class="op">;</span> <span class="co">// OK</span></a>
<a class="sourceLine" id="cb4-6" title="6"><span class="op">}</span></a>
<a class="sourceLine" id="cb4-7" title="7"><span class="kw">void</span> bar <span class="op">(</span><span class="kw">int</span> x<span class="op">,</span> <span class="kw">int</span> <span class="kw">const</span> y<span class="op">)</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb4-8" title="8">    <span class="kw">typeof</span><span class="op">(</span>x<span class="op">)</span> a <span class="op">=</span> x<span class="op">;</span></a>
<a class="sourceLine" id="cb4-9" title="9">    <span class="kw">typeof</span><span class="op">(</span>y<span class="op">)</span> b <span class="op">=</span> y<span class="op">;</span></a>
<a class="sourceLine" id="cb4-10" title="10">    <span class="kw">int</span> <span class="op">*</span> c <span class="op">=</span> <span class="op">&amp;</span>a<span class="op">;</span></a>
<a class="sourceLine" id="cb4-11" title="11">    <span class="kw">int</span> <span class="op">*</span> d <span class="op">=</span> <span class="op">&amp;</span>b<span class="op">;</span> <span class="co">// not OK, qualifier discarded, GCC warns/errors</span></a>
<a class="sourceLine" id="cb4-12" title="12"><span class="op">}</span></a></code></pre></div>
<p>The feature is more limited than generic C declarations and than the corresponding C++ feature. A declaration using <code>__auto_type</code> must be initialized, must only consist of a single declarator, and may not have any part of its type specified at all; it must infer the entire object type from the initializer value, and cannot therefore be used in combination with <code>*</code> or <code>[]</code> the way <code>auto</code> can in C++; there must be no type specifiers in the sequence apart from the <code>auto</code>.</p>
<p>The <code>auto</code> used as a complete type specifier may still be used in conjunction with qualifiers, attributes and with other storage-class specifiers:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb5-1" title="1"><span class="kw">void</span> baz <span class="op">(</span><span class="kw">int</span> x<span class="op">,</span> <span class="kw">int</span> <span class="kw">const</span> y<span class="op">)</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb5-2" title="2">    <span class="kw">__auto_type</span> <span class="kw">const</span> a <span class="op">=</span> x<span class="op">;</span></a>
<a class="sourceLine" id="cb5-3" title="3">    <span class="kw">__auto_type</span> b <span class="op">=</span> y<span class="op">;</span></a>
<a class="sourceLine" id="cb5-4" title="4">    <span class="kw">static</span> <span class="kw">__auto_type</span> c <span class="op">=</span> <span class="dv">1</span><span class="bu">ul</span><span class="op">;</span> <span class="co">// OK</span></a>
<a class="sourceLine" id="cb5-5" title="5">    <span class="kw">int</span> <span class="op">*</span> pa <span class="op">=</span> <span class="op">&amp;</span>a<span class="op">;</span>              <span class="co">// not OK</span></a>
<a class="sourceLine" id="cb5-6" title="6">    <span class="kw">int</span> <span class="kw">const</span> <span class="op">*</span> pb <span class="op">=</span> <span class="op">&amp;</span>b<span class="op">;</span>        <span class="co">// OK</span></a>
<a class="sourceLine" id="cb5-7" title="7"></a>
<a class="sourceLine" id="cb5-8" title="8">    <span class="kw">int</span> <span class="op">*</span> pc <span class="op">=</span> <span class="op">&amp;</span>c<span class="op">;</span>              <span class="co">// not OK, incompatible with unsigned long *</span></a>
<a class="sourceLine" id="cb5-9" title="9"><span class="op">}</span></a></code></pre></div>
<p>In order to avoid either specifying the wording for “same type”, which caused difficulty in accepting revision 5 of this proposal, or allowing different variables with the same syntactic specifier to infer different object types, we propose adding a new syntax constraint to exactly match the current GNU C behaviour that allows only one declarator per whole declaration using <code>__auto_type</code>. We expect implementations to gradually establish practice for how this rule should be relaxed as users explore the design space. As with the restriction against partially-specified types, we hope that implementations will support a more complete, C++-like extended feature that builds on current practice as users start to demand it, but do not standardize invention.</p>
<h3 id="alternative-keywords">Alternative keywords</h3>
<p>The original keyword that GNU C uses for this feature is <code>__auto_type</code> whereas C++ already has a mostly equivalent feature that uses the existing <code>auto</code> specifier. We leave the choice between the use of the two keywords open; in the proposed wording we use <code>AUTOTYPE</code> as a placeholder.</p>
<h3 id="direct-coding-instead-of-the-__auto_type-feature">Direct coding instead of the <code>__auto_type</code> feature</h3>
<p>C has accepted final wording for <code>typeof</code> and it is therefore now possible to declare an object in terms of the type of its initializer by writing:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb6-1" title="1"><span class="kw">typeof</span><span class="op">(((</span><span class="kw">void</span><span class="op">)</span><span class="dv">0</span><span class="op">,</span> init<span class="op">))</span> var <span class="op">=</span> init<span class="op">;</span></a></code></pre></div>
<p>The main problem with this is the repetition. There is a maintenance burden to any use outside of macro expansion; for the case that <code>init</code> has a VM type, there is a potential side effect repetition; and readability is harmed for nontrivial expressions (which may be quite long). Practice shows that implementations do not need this repetition. They already know what the type of an initializing expression is, and are able to insert it into the specifiers implicitly. Therefore, the language should not force the use of a repeating construct when one is not necessary.</p>
<h2 id="impact">Impact</h2>
<p>Implementation burden for this feature is low. Conforming C implementations are already able to delay fixing the type of a variable being declared until after seeing the initializer, as this is required for unspecified-array-size, where the element type of the array is known but the number of elements (and thus the complete type of the array object) is only known after the entire initializer right-hand-side has been seen. This feature therefore requires only a relatively minor change to existing machinery required for a conforming implementation. There is no ABI or runtime impact. The feature is purely syntactic.</p>
<h3 id="bit-fields">Bit-fields</h3>
<p>The definition of bit-fields in C is underspecified, in that their types are only known if an lvalue expression of a bit-field additionally undergoes integer promotion. If no such promotion is performed, for example in a <code>_Generic</code> or comma expression, implementations diverge in their interpretation of the standard. Some always produce one of the types <code>bool</code>, <code>signed int</code> or <code>unsigned</code> <code>int</code>, others produce some implementation defined types that reflect the width of the bit-field. The latter are not integer types in the sense of the standard because they only have to convert under promotion and need not to have any other property of integers, and, usually don’t have documented declaration syntax. It is not the place of this proposal here to sort out this inconsistency between different interpretations of the standard. This proposal specifies the feature in terms of the type produced by lvalue conversion, array-to-pointer and function-to-pointer conversion; whatever an implementation does there for bit-fields, should be good enough.</p>
<h3 id="combined-definitions-and-compatible-types">Combined definitions and compatible types</h3>
<p>The semantics of underspecified declarations become complicated if they contain definitions for several objects where the inferred type has to be consistent. In revision 5 the choice was that inferred types have to be the same, only having compatible types is not sufficient. This is particularly important for integer types, where mixing different enumeration types would have an ambiguity which type is chosen.</p>
<p>This partially caused revision 5 to be rejected at the January 2022 WG14 meeting and therefore the proposal resolves this difficulty by eliminating the syntax that would allow for any ambiguity here. Declarations using inferred types must now form separate declarations in line with existing GNU C practice.</p>
<h3 id="combined-definitions-and-variably-modified-types">Combined definitions and variably modified types</h3>
<p>Revision 5 included a consistency problem in that different types within the same definition could not be checked for consistent VM elements. This inconsistency is removed by not supporting multiple declarations within a single statement, so there is no longer any constraint to satisfy.</p>
<p>This behavior is ensured by the wording for underspecified declarations as it is proposed in N2952.</p>
<h3 id="specifiers">Specifiers</h3>
<p><code>AUTOTYPE</code> can be used in combination with other storage-class specifiers such as <code>static</code>, <code>register</code>, etc., the only one with which is not allowed to combine is <code>typeof</code>.</p>
<p><code>auto</code> now has no effect if it is not used to infer a type. We expect implementations to continue to warn as a matter of QoI. This does not break any existing conforming code.</p>
<h3 id="scope">Scope</h3>
<p>Existing practice in GNU C is that the identifier being declared has scope beginning after the end of the full-declaration, as opposed to all other identifiers which enter scope at the end of their declarator. This behavior is ensured by the wording for underspecified declarations as it is proposed in N2952.</p>
<h3 id="ambiguities-with-type-definitions">Ambiguities with type definitions</h3>
<p>Since identifiers may be redeclared in inner scopes, ambiguities with identifiers that are type definitions could occur. We resolve that ambiguity by reviving a rule that solved the same problem when C still had the implicit <code>int</code> rule. This is done in <code class="text">6.7.8 p3</code> (Type definitions) by adding the following phrase:</p>
<blockquote>
<ins>
<p>If the identifier is redeclared in an inner scope the inner declaration shall not be underspecified.</p>
</blockquote>
<h2 id="implementation-experience">Implementation Experience</h2>
<p><code>__auto_type</code> is implemented by most (all?) compilers implementing the GNU C dialect or aiming for GCC compatibility. A non-exhaustive list includes: GCC, Clang, Intel CC, Helix QAC, Klocwork, armCC. It is generally used to implement type-generic macros in library headers. It does not appear to be widely used by developers in application code but is heavily tested by virtue of its appearance in Standard header implementations.</p>
<p>Many compilers exist which borrow components from GCC or Clang, and therefore inherit this feature intentionally or unintentionally.</p>
<p>A more comprehensive feature exists in C++ since C++11, which is based on template type deduction rules and can therefore use <code>auto</code> to infer parts of a partially-specified type, such as specifying that a declaration creates a pointer or reference but not what it is a pointer or reference to. This is in near-universal use by millions of C++ developers every day.</p>
<p>This <code>auto</code> feature from C++ is also implemented by clang for their C frontend. In addition, clang also extends the <code>__auto_type</code> feature such that it covers the same semantics as their <code>auto</code>, thus presenting essentially a single extension that can be spelled with two different keywords, <code>auto</code> and <code>__auto_type</code>.</p>
<p>Specifying a feature closer to the C++ specifier would require substantial original wording in the Standard since C does not include templates, which the C++ feature is defined in terms of. Usability experience from C++ might set user expectation to be able to write <code>auto * foo = ...</code>. Therefore the text leaves room for extensions; declarations with several declarators or with pointer derivations, for example, are undefined and not constraints. There is at least already one implementation that provides such a wider functionality, clang, and our intent is not to constrain these too much.</p>
<h2 id="proposed-wording">Proposed wording</h2>
<p>Changes are proposed against the wording in C23 draft n2731 to which the accepted changes concerning keywords and N2952 have been added. Green and underlined text is new text. The token <code>AUTOTYPE</code> has to be replaced by either <code>__auto_type</code> or <code>auto</code>, whichever is choosen by WG14 to represent the feature.</p>
<h3 id="linkage-of-identifiers-6.2.2">Linkage of identifiers (6.2.2)</h3>
<p>Modify</p>
<blockquote>
<p>5 If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier <code>extern</code> . If the declaration of an identifier for an object has file scope and no storage-class specifier <ins>or only the specifier <code>AUTOTYPE</code></ins>, its linkage is external.</p>
</blockquote>
<h3 id="keywords-6.4.1">Keywords (6.4.1)</h3>
<p>If necessary, add <code>__auto_type</code> to the list of keywords. If the choice falls on using <code>auto</code> instead, no change is necessary.</p>
<h3 id="storage-class-specifiers-6.7.1">Storage-class specifiers (6.7.1)</h3>
<p>If necessary, add <code>__auto_type</code> to the list of storage-class specifiers. If the choice falls on using <code>auto</code> instead, no change is necessary.</p>
<p>Modify the constraints section</p>
<blockquote>
<p><strong>Constraints</strong></p>
</blockquote>
<blockquote>
<p>2 At most, one storage-class specifier may be given in the declaration specifiers in a declaration, except that <code>thread_local</code> may appear with <code>static</code> or <code>extern</code><ins>, and that <code>AUTOTYPE</code> may appear with all others but with <code>typedef</code></ins>.<sup>127)</sup></p>
</blockquote>
<blockquote>
<p>3 In the declaration of an object with block scope, if the declaration specifiers include <code>thread_local</code>, they shall also include either <code>static</code> or <code>extern</code>. If <code>thread_local</code> appears in any declaration of an object, it shall be present in every declaration of that object.</p>
</blockquote>
<blockquote>
<p>4 <code>thread_local</code> shall not appear in the declaration specifiers of a function declaration. <ins><code>AUTOTYPE</code> shall only appear in the declaration specifiers of an identifier with file scope if the type is to be inferred from an initializer.</ins></p>
</blockquote>
<p>Add a new paragraph</p>
<blockquote>
<ins>
9 If <code>AUTOTYPE</code> appears with another storage-class specifier, or if it appears in a declaration at file scope it is ignored for the purpose of determining a storage duration or linkage. It then only indicates that the declared type may be inferred.
</ins>
</blockquote>
<p>Modify the forward references section</p>
<blockquote>
<p><strong>Forward references:</strong> type definitions (6.7.8)<ins>, type inference (6.7.10)</ins>.</p>
</blockquote>
<h3 id="type-specifiers-6.7.2">Type specifiers (6.7.2)</h3>
<p>Modify the beginning of the following paragraph of the Constraints section</p>
<blockquote>
<p><del>At</del><ins>Except where the type is inferred (6.7.10), at</ins> least one type specifier shall be given in the declaration specifiers in each declaration, …</p>
</blockquote>
<p>Add a new paragraph in the Sematics section after paragraph 4</p>
<blockquote>
<ins>
4’ For a declaration such that the declaration specifiers contain no type specifier a mechanism to infer the type from an initializer is discussed in 6.7.10. In such a declaration, optional elements, if any, of a sequence of declaration specifiers appertain to the inferred type (for qualifiers and attribute specifiers) or to the declared objects (for alignment specifiers).
</ins>
</blockquote>
<h3 id="type-definitions-6.7.8">Type definitions (6.7.8)</h3>
<p>Add to the end of paragraph 3 of the Sematics section</p>
<blockquote>
<p>… A typedef name shares the same name space as other identifiers declared in ordinary declarators. <ins> If the identifier is redeclared in an enclosed block the inner declaration shall not be such that the type is inferred.</ins></p>
</blockquote>
<h3 id="declarations-6.7">Declarations (6.7)</h3>
<p>Add a new normative clause</p>
<blockquote>
<ins>
<p><strong>6.7.10 Type inference</strong></p>
</blockquote>
<blockquote>
<ins>
<p><strong>Constraints</strong></p>
</blockquote>
<blockquote>
<ins>
<p>1 A declaration for which the type is inferred shall contain the storage-class specifier <code>AUTOTYPE</code>.</p>
</blockquote>
<blockquote>
<ins>
<p><strong>Description</strong></p>
</blockquote>
<blockquote>
<ins>
<p>2 For such a declaration that is the definition of an object the init-declarator shall have one of the forms</p>
</blockquote>
<blockquote>
<blockquote>
<ins>
<pre>
direct-declarator = assignment-expression
direct-declarator = { assignment-expression }
direct-declarator = { assignment-expression , }
</pre>
</ins>
</blockquote>
</blockquote>
<blockquote>
<ins>
<p>The declared type is the type of the assignment expression after lvalue, array to pointer or function to pointer conversion, additionally qualified by qualifiers and amended by attributes as they appear in the declaration specifiers, if any.<sup>FNT1)</sup> If the direct declarator is not of the form</p>
</blockquote>
<blockquote>
<blockquote>
<ins>
<pre>
identifier attribute-specifier-sequence<sub>opt</sub>
</pre>
</ins>
</blockquote>
</blockquote>
<blockquote>
<ins>
<p>possibly enclosed in balanced pairs of parenthesis the behavior is undefined.</p>
</blockquote>
<blockquote>
<ins>
<p><sup>FNT1)</sup> The scope rules as described in 6.2.1 also prohibit the use of the identifier of the declarator within the assignment expression.</p>
</blockquote>
<h3 id="non-normative-additions">Non-normative additions</h3>
<h4 id="note-and-examples">note and examples</h4>
<p>Additionally, add the following non-normative text to the new clause.</p>
<blockquote>
<ins>
<p>3 <strong>NOTE</strong> Such a declaration that also defines a structure or union type violates a constraint. Here, the identifier <code>a</code> which is not ordinary but in the name space of the structure type is declared.</p>
</blockquote>
<blockquote>
<blockquote>
<div class="sourceCode" id="cb7"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb7-1" title="1">AUTOTYPE p <span class="op">=</span> <span class="op">(</span><span class="kw">struct</span> <span class="op">{</span> <span class="kw">int</span> a<span class="op">;</span> <span class="op">}</span> <span class="op">*)</span><span class="dv">0</span><span class="op">;</span></a></code></pre></div>
</blockquote>
</blockquote>
<blockquote>
<ins>
<p>Even a forward declaration of a structure tag</p>
</blockquote>
<blockquote>
<blockquote>
<div class="sourceCode" id="cb8"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb8-1" title="1"><span class="kw">struct</span> s<span class="op">;</span></a>
<a class="sourceLine" id="cb8-2" title="2">AUTOTYPE p <span class="op">=</span> <span class="op">(</span><span class="kw">struct</span> s <span class="op">{</span> <span class="kw">int</span> a<span class="op">;</span> <span class="op">}</span> <span class="op">*)</span><span class="dv">0</span><span class="op">;</span></a></code></pre></div>
</blockquote>
</blockquote>
<blockquote>
<ins>
<p>would not change that situation. A direct use of the structure definition as the type specifier ensures the validity of the declaration.</p>
</blockquote>
<blockquote>
<blockquote>
<div class="sourceCode" id="cb9"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">struct</span> s <span class="op">{</span> <span class="kw">int</span> a<span class="op">;</span> <span class="op">}</span> <span class="op">*</span> p <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></a></code></pre></div>
</blockquote>
</blockquote>
<hr />
<blockquote>
<ins>
<p>4 <strong>EXAMPLE 1</strong> Consider the following file scope definitions:</p>
</blockquote>
<blockquote>
<blockquote>
<div class="sourceCode" id="cb10"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb10-1" title="1"><span class="kw">static</span> AUTOTYPE a <span class="op">=</span> <span class="fl">3.5</span><span class="op">;</span></a>
<a class="sourceLine" id="cb10-2" title="2">AUTOTYPE p <span class="op">=</span> <span class="op">&amp;</span>a<span class="op">;</span></a></code></pre></div>
</blockquote>
</blockquote>
<blockquote>
<ins>
<p>They are interpreted as if they had been written as:</p>
</blockquote>
<blockquote>
<blockquote>
<div class="sourceCode" id="cb11"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb11-1" title="1"><span class="kw">static</span> <span class="kw">double</span> a <span class="op">=</span> <span class="fl">3.5</span><span class="op">;</span></a>
<a class="sourceLine" id="cb11-2" title="2"><span class="kw">double</span> <span class="op">*</span> p <span class="op">=</span> <span class="op">&amp;</span>a<span class="op">;</span></a></code></pre></div>
</blockquote>
</blockquote>
<blockquote>
<ins>
<p>So effectively <code>a</code> is a <code>double</code> and <code>p</code> is a <code>double*</code>. Note that the restrictions on the syntax of such declarations does not allow the declarator to be <code>*p</code>, but that the final type here nevertheless is a pointer type.</p>
</blockquote>
<hr />
<blockquote>
<ins>
<p>5 <strong>EXAMPLE 2</strong> The scope of the identifier for which the type is inferred only starts after the end of the initializer (6.2.1), so the assignment expression cannot use the identifier to refer to the object or function that is declared, for example to take its address. Any use of the identifier in the initializer is invalid, even if an entity with the same name exists in an outer scope.</p>
</blockquote>
<blockquote>
<blockquote>
<div class="sourceCode" id="cb12"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb12-1" title="1"><span class="op">{</span></a>
<a class="sourceLine" id="cb12-2" title="2">  <span class="kw">double</span> a <span class="op">=</span> <span class="dv">7</span><span class="op">;</span></a>
<a class="sourceLine" id="cb12-3" title="3">  <span class="kw">double</span> b <span class="op">=</span> <span class="dv">9</span><span class="op">;</span></a>
<a class="sourceLine" id="cb12-4" title="4">  <span class="op">{</span></a>
<a class="sourceLine" id="cb12-5" title="5">    <span class="kw">double</span> b <span class="op">=</span> b <span class="op">*</span> b<span class="op">;</span>       <span class="co">// undefined, uses uninitialized variable without address</span></a>
<a class="sourceLine" id="cb12-6" title="6">    printf<span class="op">(</span><span class="st">&quot;%g</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">,</span> a<span class="op">);</span>      <span class="co">// valid, uses &quot;a&quot; from outer scope, prints 7</span></a>
<a class="sourceLine" id="cb12-7" title="7">    AUTOTYPE a   <span class="op">=</span> a <span class="op">*</span> a<span class="op">;</span>   <span class="co">// invalid, &quot;a&quot; from outer scope is already shadowed</span></a>
<a class="sourceLine" id="cb12-8" title="8">  <span class="op">}</span></a>
<a class="sourceLine" id="cb12-9" title="9">  <span class="op">{</span></a>
<a class="sourceLine" id="cb12-10" title="10">    AUTOTYPE b   <span class="op">=</span> a <span class="op">*</span> a<span class="op">;</span>   <span class="co">// valid, uses &quot;a&quot; from outer scope</span></a>
<a class="sourceLine" id="cb12-11" title="11">    AUTOTYPE a   <span class="op">=</span> b<span class="op">;</span>       <span class="co">// valid, shadows &quot;a&quot; from outer scope</span></a>
<a class="sourceLine" id="cb12-12" title="12">    <span class="op">...</span></a>
<a class="sourceLine" id="cb12-13" title="13">    printf<span class="op">(</span><span class="st">&quot;%g</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">,</span> a<span class="op">);</span>      <span class="co">// valid, uses &quot;a&quot; from inner scope, prints 49</span></a>
<a class="sourceLine" id="cb12-14" title="14">  <span class="op">}</span></a>
<a class="sourceLine" id="cb12-15" title="15">  <span class="op">...</span></a>
<a class="sourceLine" id="cb12-16" title="16"><span class="op">}</span></a></code></pre></div>
</blockquote>
</blockquote>
<hr />
<blockquote>
<ins>
<p>6 <strong>EXAMPLE 3</strong> In the following, declarations of <code>pA</code> and <code>qA</code> are valid. The type of <code>A</code> after array-to-pointer conversion is a pointer type, and <code>qA</code> is a pointer to array.</p>
</blockquote>
<blockquote>
<blockquote>
<div class="sourceCode" id="cb13"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb13-1" title="1"><span class="kw">double</span> A<span class="op">[</span><span class="dv">3</span><span class="op">]</span> <span class="op">=</span> <span class="op">{</span> <span class="dv">0</span> <span class="op">};</span></a>
<a class="sourceLine" id="cb13-2" title="2">AUTOTYPE pA <span class="op">=</span> A<span class="op">;</span></a>
<a class="sourceLine" id="cb13-3" title="3">AUTOTYPE qA <span class="op">=</span> <span class="op">&amp;</span>A<span class="op">;</span></a></code></pre></div>
</blockquote>
</blockquote>
<hr />
<blockquote>
<ins>
<p>7 <strong>EXAMPLE 4</strong> Type inference can be used to capture the type of a call to a type-generic function. It ensures that the same type as the argument <code>x</code> is used.</p>
</blockquote>
<blockquote>
<blockquote>
<div class="sourceCode" id="cb14"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb14-1" title="1"><span class="pp">#include </span><span class="im">&lt;tgmath.h&gt;</span></a>
<a class="sourceLine" id="cb14-2" title="2">AUTOTYPE y <span class="op">=</span> cos<span class="op">(</span>x<span class="op">);</span></a></code></pre></div>
</blockquote>
</blockquote>
<blockquote>
<ins>
<p>If instead the type of <code>y</code> is explicitly specified to a different type than <code>x</code>, a diagnosis of the mismatch is not enforced.</p>
</blockquote>
<hr />
<blockquote>
<ins>
<p>8 <strong>EXAMPLE 5</strong> A type-generic macro that generalizes the <code>div</code> functions (7.22.6.2) is defined and used as follows.</p>
</blockquote>
<blockquote>
<blockquote>
<div class="sourceCode" id="cb15"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb15-1" title="1"><span class="pp">#define div(X, Y) _Generic((X)+(Y), int: div, long: ldiv, long long: lldiv)((X), (Y))</span></a>
<a class="sourceLine" id="cb15-2" title="2">AUTOTYPE z <span class="op">=</span> div<span class="op">(</span>x<span class="op">,</span> y<span class="op">);</span></a>
<a class="sourceLine" id="cb15-3" title="3">AUTOTYPE q <span class="op">=</span> z<span class="op">.</span>quot<span class="op">;</span></a>
<a class="sourceLine" id="cb15-4" title="4">AUTOTYPE r <span class="op">=</span> z<span class="op">.</span>rem<span class="op">;</span></a></code></pre></div>
</blockquote>
</blockquote>
<hr />
<blockquote>
<ins>
<p>9 <strong>EXAMPLE 6</strong> Definitions of objects with inferred type are valid in all contexts that allow the initializer syntax as described. In particular they can be used to ensure type safety of <code>for</code>-loop controlling expressions.</p>
</blockquote>
<blockquote>
<blockquote>
<ins>
<div class="sourceCode" id="cb16"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb16-1" title="1"><span class="cf">for</span> <span class="op">(</span>AUTOTYPE i <span class="op">=</span> j<span class="op">;</span> i <span class="op">&lt;</span> <span class="dv">2</span><span class="op">*</span>j<span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb16-2" title="2">   <span class="op">...</span></a>
<a class="sourceLine" id="cb16-3" title="3"><span class="op">}</span></a></code></pre></div>
</ins>
</blockquote>
</blockquote>
<blockquote>
<ins>
<p>Here, regardless of the integer rank or signedness of the type of <code>j</code>, <code>i</code> will have the non-atomic unqualified type of <code>j</code>. So, after lvalue conversion and possible promotion, the two operands of the <code>&lt;</code> operator in the controlling expression are guaranteed to have the same type, and, in particular, the same signedness.</p>
</blockquote>
<hr />
<h4 id="storage-class-specifiers-6.7.1-1">Storage-class specifiers (6.7.1)</h4>
<p>Adapt the changed p6 as of N2952</p>
<blockquote>
<p>6 Storage-class specifiers specify various properties of identifiers and declared features; storage duration (<code>static</code> in block scope, <code>thread_local</code>, <code>auto</code>, <code>register</code>), linkage (<code>extern</code>, <code>static</code> in file scope, <code>typedef</code>) and type (<code>typedef</code><ins>, <code>AUTOTYPE</code></ins>). The meanings of the various linkages and storage durations were discussed in 6.2.2 and 6.2.4, <code>typedef</code> is discussed in 6.7.8<ins>, type inference using <code>AUTOTYPE</code> is specified in 6.7.10</ins>.</p>
</blockquote>
<h4 id="undefined-behavior-j.2">Undefined behavior (J.2)</h4>
<p>Add two new items to the list</p>
<blockquote>
<ul>
<li>…</li>
<li>The initializer for an aggregate or union, other than an array initialized by a string literal, is not a brace-enclosed list of initializers for its elements or members (6.7.9).</li>
<li><ins>
A declaration for which a type is inferred contains pointer, array or function declarators (6.7.10).</li>
<li><ins>
A declaration for which a type is inferred contains no or more than one declarators (6.7.10).</li>
<li>An identifier with external linkage is used, but in the program there does not exist exactly one external definition for the identifier, or the identifier is not used and there exist multiple external definitions for the identifier (6.9).</li>
<li>…</li>
</ul>
</blockquote>
<h4 id="common-extensions-j.5">Common extensions (J.5)</h4>
<p>Add a new clause</p>
<blockquote>
<ins>
<p><strong>J.5.18 Type inference</strong></p>
</blockquote>
<blockquote>
<ins>
<p>1 A declaration for which a type is inferred (6.7.10) may additionally accept pointer declarators, function declarators and may have more than one declarator.</p>
</blockquote>
<h2 id="questions-to-wg14">Questions to WG14</h2>
<h3 id="keyword">Keyword</h3>
<p>Does WG14 prefer the use keyword <code>auto</code> for type inference as proposed in N2953?</p>
<h3 id="acceptance">Acceptance</h3>
<p>Does WG14 want to include the type inference feature of N2953 together with the underspecified declaration feature of N2952 into C23?</p>
<h2 id="references">References</h2>
<ul>
<li><a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2731.pdf">C23</a></li>
<li><a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2890.pdf">Improve type generic programming</a></li>
<li><a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2927.htm">Not so magic typeof</a></li>
<li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf">C++11</a></li>
<li><a href="https://gcc.gnu.org/onlinedocs/gcc/Typeof.html#Typeof">GCC <code>typeof</code> and <code>__auto_type</code></a></li>
</ul>
</body>
</html>
