657. unclear requirement about header inclusion

Section: 20.5.2.2 [using.headers] Status: NAD Submitter: Gennaro Prota Opened: 2007-03-14 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [using.headers].

View all issues with NAD status.

Discussion:

20.5.2.2 [using.headers] states:

A translation unit shall include a header only outside of any external declaration or definition, [...]

I see three problems with this requirement:

  1. The C++ standard doesn't define what an "external declaration" or an "external definition" are (incidentally the C99 standard does, and has a sentence very similar to the above regarding header inclusion).

    I think the intent is that the #include directive shall lexically appear outside *any* declaration; instead, when the issue was pointed out on comp.std.c++ at least one poster interpreted "external declaration" as "declaration of an identifier with external linkage". If this were the correct interpretation, then the two inclusions below would be legal:

      // at global scope
      static void f()
      {
    # include <cstddef>
      }
    
      static void g()
      {
    # include <stddef.h>
      }
    

    (note that while the first example is unlikely to compile correctly, the second one may well do)

  2. as the sentence stands, violations will require a diagnostic; is this the intent? It was pointed out on comp.std.c++ (by several posters) that at least one way to ensure a diagnostic exists:

    [If there is an actual file for each header,] one simple way to implement this would be to insert a reserved identifier such as __begin_header at the start of each standard header. This reserved identifier would be ignored for all other purposes, except that, at the appropriate point in phase 7, if it is found inside an external definition, a diagnostic is generated. There's many other similar ways to achieve the same effect.

    --James Kuyper, on comp.std.c++

  3. is the term "header" meant to be limited to standard headers? Clause 17 is all about the library, but still the general question is interesting and affects one of the points in the explicit namespaces proposal (n1691):

    Those seeking to conveniently enable argument-dependent lookups for all operators within an explicit namespace could easily create a header file that does so:

        namespace mymath::
        {
            #include "using_ops.hpp"
        }
    

Proposed resolution:

Rationale:

We believe that the existing language does not cause any real confusion and any new formulation of the rules that we could come up with are unlikely to be better than what's already in the standard.