<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 456: Traditional C header files are overspecified</title>
<meta property="og:title" content="Issue 456: Traditional C header files are overspecified">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue456.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#CD1">CD1</a> status.</em></p>
<h3 id="456"><a href="lwg-defects.html#456">456</a>. Traditional C header files are overspecified</h3>
<p><b>Section:</b> 16.4.2.3 <a href="https://wg21.link/headers">[headers]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Bill Plauger <b>Opened:</b> 2004-01-30 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#headers">issues</a> in [headers].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>

<p>The C++ Standard effectively requires that the traditional C headers
(of the form &lt;xxx.h&gt;) be defined in terms of the newer C++
headers (of the form &lt;cxxx&gt;). Clauses 17.4.1.2/4 and D.5 combine
to require that:</p>

<ul>
 <li>Including the header &lt;cxxx&gt; declares a C name in namespace std.</li>

 <li> Including the header &lt;xxx.h&gt; declares a C name in namespace std
    (effectively by including &lt;cxxx&gt;), then imports it into the global
    namespace with an individual using declaration.</li>
</ul>

<p>
The rules were left in this form despited repeated and heated objections
from several compiler vendors. The C headers are often beyond the direct
control of C++ implementors. In some organizations, it's all they can do
to get a few #ifdef __cplusplus tests added. Third-party library vendors
can perhaps wrap the C headers. But neither of these approaches supports
the drastic restructuring required by the C++ Standard. As a result, it is
still widespread practice to ignore this conformance requirement, nearly
seven years after the committee last debated this topic. Instead, what is
often implemented is:
</p>

<ul>
 <li> Including the header &lt;xxx.h&gt; declares a C name in the
 global namespace.</li> 

 <li> Including the header &lt;cxxx&gt; declares a C name in the
 global namespace (effectively by including &lt;xxx.h&gt;), then
 imports it into namespace std with an individual using declaration.</li>
</ul>

<p>
The practical benefit for implementors with the second approach is that
they can use existing C library headers, as they are pretty much obliged
to do. The practical cost for programmers facing a mix of implementations
is that they have to assume weaker rules:</p>

<ul>
  <li> If you want to assuredly declare a C name in the global
  namespace, include &lt;xxx.h&gt;. You may or may not also get the
  declaration in namespace std.</li>

  <li> If you want to assuredly declare a C name in namespace std,
  include &lt;cxxx&gt;. You may or may not also get the declaration in
  the global namespace.</li>
</ul>

<p>
There also exists the <i>possibility</i> of subtle differences due to
Koenig lookup, but there are so few non-builtin types defined in the C
headers that I've yet to see an example of any real problems in this
area.
</p>

<p>
It is worth observing that the rate at which programmers fall afoul of
these differences has remained small, at least as measured by newsgroup
postings and our own bug reports. (By an overwhelming margin, the
commonest problem is still that programmers include &lt;string&gt; and can't
understand why the typename string isn't defined -- this a decade after
the committee invented namespace std, nominally for the benefit of all
programmers.)
</p>

<p>
We should accept the fact that we made a serious mistake and rectify it,
however belatedly, by explicitly allowing either of the two schemes for
declaring C names in headers.
</p>

<p><i>[Sydney: This issue has been debated many times, and will
  certainly have to be discussed in full committee before any action
  can be taken.  However, the preliminary sentiment of the LWG was in
  favor of the change.  (6 yes, 0 no, 2 abstain) Robert Klarer
  suggests that we might also want to undeprecate the
  C-style <code>.h</code> headers.]</i></p>




<p id="res-456"><b>Proposed resolution:</b></p>
<p>
Add to 16.4.2.3 <a href="https://wg21.link/headers">[headers]</a>, para. 4:
</p>

<blockquote><p>
Except as noted in clauses 18 through 27 and Annex D, the contents of each
header <i>cname</i> shall be the same as that of the corresponding header
<i>name.h</i>, as specified in ISO/IEC 9899:1990 Programming Languages C (Clause
7), or ISO/IEC:1990 Programming Languages-C AMENDMENT 1: C Integrity, (Clause
7), as appropriate, as if by inclusion. In the C++ Standard Library, however,
the declarations <del>and definitions</del> (except for names which are defined
as macros in C) are within namespace scope (3.3.5) of the namespace std. 
<ins>It is unspecified whether these names are first declared within the global
namespace scope and are then injected into namespace std by explicit
using-declarations (9.10 <a href="https://wg21.link/namespace.udecl">[namespace.udecl]</a>).</ins>
</p></blockquote>

<p>
Change  [depr.c.headers], para. 2-3:
</p>

<blockquote>
<p>
-2- Every C header, each of which has a name of the form <i>name.h</i>, behaves
as if each name placed in the Standard library namespace by the corresponding
<i>cname</i> header is <del>also</del> placed within the <ins>global</ins>
namespace scope<ins>.</ins> <del>of the namespace <code>std</code> and is followed
by an explicit <i>using-declaration</i> (9.10 <a href="https://wg21.link/namespace.udecl">[namespace.udecl]</a>).</del>
<ins>It is unspecified whether these names are first declared or defined within
namespace scope (6.4.6 <a href="https://wg21.link/basic.scope.namespace">[basic.scope.namespace]</a>) of the namespace
<code>std</code> and are then injected into the global namespace scope by explicit
using-declarations (9.10 <a href="https://wg21.link/namespace.udecl">[namespace.udecl]</a>).</ins>
</p>
<p>
-3- [<i>Example:</i> The header <code>&lt;cstdlib&gt;</code> <ins>assuredly</ins>
provides its declarations and definitions within the namespace <code>std</code>.
<ins>It may also provide these names within the global namespace.</ins> The
header <code>&lt;stdlib.h&gt;</code> <del>makes these available also in</del>
<ins>assuredly provides the same declarations and definitions within</ins> the
global namespace, much as in the C Standard. <ins>It may also provide these
names within the namespace <code>std</code>.</ins> <i>-- end example</i>]
</p>
</blockquote>





</body>
</html>
