ISO/ IEC JTC1/SC22/WG21 N0723


Accredited Standards Committee X3       Doc No: X3J16/95-0123   WG21/N0723
Information Processing Systems          Date:    Jun 30, 1995
Operating under the procedures of       Project: Programming Language C++
American National Standards Institute   Ref Doc:
                                        Reply to: Josee Lajoie
                                                  (josee@vnet.ibm.com)
 

Linkage Issues and Proposed Resolutions
=======================================
 
o Linkage
=========
 
 *Issue 473:
  ----------
  What is the linkage of local static variables?
 
  7.1.1 paragraph 4 says:
  "A name declared with a static specifier in a scope other than class
   scope (3.3.5) has internal linkage."
 
  This implies that both functions in the following translation unit are
  modifying the same object:
 
     void f() {static int x; x++;}
     void g() {static int x; x++;}
 
  Proposal 473:
  -------------
  Change 7.1.1 paragraph 4 to say:
  "A name declared with a static specifier in a namespace scope has
   internal linkage, and in a block scope has no linkage."
 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
 *Issue 437:
  ----------
  How do block scope extern declarations link with previous declarations?
 
    static x; /* internal linkage */
 
    void f() {
      auto x;  /* no linkage */
      {
        extern x;  /* linkage unclear by 3.5, since the prior visible
                      declaration has no linkage.
 
                      external linkage by 7.1.1, since there is no visible
                      name with namespace scope. */
      }
   }
 
 
  3.5 paragraph 6 says:
    "The name of a function declared in a block scope or a variable
     declared extern in a block scope has linkage, either internal or
     external to match the linkage of prior visible declarations of the
     same name in the same translation unit, but if there is no prior
     visible declaration it has external linkage."
 
  7.1.1 paragraph 5 says:
    "...An object or function introduced by a declaration with an
     extern specifier has external linkage unless the declaration
     matches a visible prior declaration at namespace scope of the same
     object or function, in which case the object or function has the
     linkage specified by the prior declaration."
 
  Proposal 437:
  -------------
  Change the sentence in 3.5 as follows:
    "The name of a function declared in a block scope or a variable
     declared extern in a block scope has external linkage, unless the
     declaration matches a visible declaration of namespace scope with
     internal linkage, in which case the object or function has internal
     linkage."
 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
 *Issue 461:
  ----------
  Do namespace names have linkage?
 
  3.5 [basic.link] does not discuss namespaces.
 
  Discussion 461:
  ---------------
  I believe namespaces must have external linkage for the following
  example to work:
 
     // ----- File 1 -----
     struct A {
       void f();
     };
 
     // ----- File 2 -----
     namespace A {
       void f();
     }
 
  The class A and the namespace A both have external linkage.
  When files 1 and 2 are linked together, the name A refers to
  different entities in both files.  This causes the program to result
  in undefined behavior.
 
  Proposal 461:
  -------------
  Add a bullet to paragraph 4:
    -- a namespace (7.3)
 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
 
o Names
=======
 
  In edit-554 Mike Anderson noticed that 3 [basic] paragraph 8 needs to
  be changed to:
 
  "Two names are *the same* (with "the same" in italics) if
   -- they are identifiers composed with the same character sequences; or
   -- they are the names of overloaded operator functions formed with the
      same operator;
   -- they are the names of user-defined conversion functions formed with
      the same type.
   "
 
  This appropriate notion of "same name" is needed to properly address
  the issues on linking below.
 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
 
o Linking
=========
 
  Issue L1:
  ---------
 
  Given the definition of 'same name', 3.5 [basic.link] paragraph 8 says:
 
  "8 Two names that are the same and that are declared in different scopes
     shall denote the same object, function, type or template if:
     -- both names have external linkage or else both names have internal
        linkage and are declared in the same translation unit; and
     -- both names refer to members of the same namespace; and
     -- when both names denote functions or function templates, the function
        types are identical for purposes of overloading.
  "
 
  o "...that are declared in different scopes..."
    Are two names declared in the same namespace but in different
    translation units considered to be 'different scopes'?
 
  o This paragraph does not discuss namespace names or reference names
    (which are excluded by the terms object and function names).
 
  o "when both names denote ... function templates, the function
     types are identical for purposes of overloading."
    What does it mean for two function templates to have identical types?
    I believe this sentence should discuss function template
    specializations instead.
 
  Proposal L1a:
  -------------
  Replace the beginning of paragraph 4 with:
  "Two names that are the same and that are declared in different scopes
   or that are declared in the same namespace in different translation
   units shall denote the same object, function, reference, type,
   namespace or template if: ..."
 
  Replace the last bullet of paragraph 4 with:
  "when both names denote ... function template specializations..."
 
 
  Paragraph 9 says:
 
  "9 After all adjustments of types (during which typedefs (7.1.3) are
     replaced by their definitions), the types specified by all
     declarations of a particular external name shall be identical..."
 
  This should be reworded to indicate it does not apply to namespace
  or template names.
 
  Proposal L1b:
  -------------
  Modify paragraph 9 to be as follows:
  "After all adjustments of types (during which typedefs (7.1.3) are
   replaced by their definitions), the types specified by all
   declarations of a particular object, reference, function, function
   template specialization shall be identical..."
 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
  In message core-5790, Fergus Henderson notes:
 
  [Fergus]:
  For example, if the following occurs in two translation units, does
  it violate the ODR?
 
     typedef struct {
        // ...
     } *NodePtr;
     struct List {
        NodePtr p;
     };
 
  [Josee]:
  Yes, it does break the ODR.
  See later on in 7.1.3 [dcl.typedef] paragraph 5.
  "If an unnamed class is defined in a typedef declaration but the
   declaration does not declare a class type, the name of the class
   for linkage purpose is a dummy name."
 
  [Fergus]:
  Where in the working paper does it say that the "dummy name" will be
  different in different translation units?
 
  I think that is an omission which should be rectified.
 
  Proposal N1:
  ------------
  After the following sentence in 7.1.3[[dcl.typedef] paragraph 5:
    "An unnamed class defined in a declaration with a typedef specifier
     gets a dummy name."
  add:
    "Two unnamed classes with identical member lists that are defined
     in different translation units receive different dummy names."
 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
  Issue 502:
  --------
  The rules described in 7.1.3 [dcl.typedef] paragraph 5 apply to
  enumeration types as well.
 
  Proposal 502:
  -------------
  Change the text in 7.1.3 p5 as follows:
  "An unnamed class _or enum_ defined in a typedef declaration gets a
   dummy name.  For linkage purposes only, the first typedef-name
   declared by the declaration is used to denote the class type _or
   enumeration type_ in the place of the dummy name.
   ...
   The typedef-name is still only a synonym for the dummy name and
   shall not be used where a true class name _or enum name_ is required.
   ...
   If an unnamed class _or enum_ is defined in a typedef declaration
   but the declaration does not declare a class type _or enumeration
   type_, the name of the class for linkage purposes is a dummy name."
 
  And delete paragraph 6, which becomes unnecessary.
 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
 
o Inline functions
==================
 
  Issue 454:
  ----------
  Can two inline functions call one another?
 
  7.1.2 [dcl.fct.spec] paragraph 3 says:
  "A call to an inline function shall not precede its definition."
 
  This prohibits existing practice.
 
    class X {
      void f() { g(); }
      void g() { h(); }
    };
 
  Proposal 454:
  -------------
  Replace the sentence above in 7.1.2 p3 with:
    "An inline function must be declared inline before it is used."
 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
 
o extern "LANG" issues
======================
 
  Issue 8:
  --------
  Does a pointer to a "C" function have a different type than a pointer
  to a C++ function?
 
  See langkage.july95 paper.
 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
 
  Issue 486:
  ----------
  What is the linkage of a name affected by multiple linkage specifications?
 
  The grammar allows multiple linkage specifications, like
 
    extern "C" extern "C++" int foo() ;
 
    All 7.5[dcl.link] paragraph 2 says is "linkage specifications nest."
 
  Proposal 486:
  -------------
  Add to 7.5p2:
    "When linkage specifications nest the innermost one determines the
     linkage".