Title
Identically-named variables, one internally and one externally linked, allowed?
Status
c++17
Section
6.6 [basic.link]
Submitter
Steve Adamczyk

Created on 2003-07-02.00:00:00 last changed 36 months ago

Messages

Date: 2016-11-15.00:00:00

Proposed resolution (November, 2016):

Change 6.6 [basic.link] paragraph 6 as follows:

...Otherwise, if no matching entity is found, the block scope entity receives external linkage. If, within a translation unit, the same entity is declared with both internal and external linkage, the program is ill-formed. [Example:

  static void f();
  static int i = 0;     // #1
  void g() {
    extern void f();    // internal linkage
    int i;              // #2: i has no linkage
    {
      extern void f();  // internal linkage
      extern int i;     // #3 external linkage, ill-formed
    }
  }

There are three objects named i in this program. The object with internal linkage introduced by the declaration in global scope (line #1 ), the object with automatic storage duration and no linkage introduced by the declaration on line #2, and the object with static storage duration and external linkage introduced by the declaration on line #3. Without the declaration at line #2, the declaration at line #3 would link with the declaration at line #1. Because the declaration with internal linkage is hidden, however, #3 is given external linkage, making the program ill-formed.end example]

Date: 2006-10-15.00:00:00

Notes from the October 2006 meeting:

The CWG decided that it would be better to make a program with this kind of linkage mismatch ill-formed instead of having undefined behavior.

Date: 2006-04-15.00:00:00

Notes from the April 2006 meeting:

According to 6.6 [basic.link] paragraph 9, the two variables with linkage in the proposed example are not “the same entity” because they do not have the same linkage. Some other formulation will be needed to describe the relationship between those two variables.

Date: 2005-10-15.00:00:00

Proposed resolution (October, 2005) [SUPERSEDED]:

Change 6.6 [basic.link] paragraph 6 as indicated:

...Otherwise, if no matching entity is found, the block scope entity receives external linkage. If, within a translation unit, the same entity is declared with both internal and external linkage, the behavior is undefined.

[Example:

    static void f();
    static int i = 0;            // 1
    void g () {
        extern void f ();        // internal linkage
        int i;                   // 2: i has no linkage
        {
            extern void f ();    // internal linkage
            extern int i;        // 3: external linkage
        }
    }

There are three objects named i in this program. The object with internal linkage introduced by the declaration in global scope (line //1 ), the object with automatic storage duration and no linkage introduced by the declaration on line //2, and the object with static storage duration and external linkage introduced by the declaration on line //3. Without the declaration at line //2, the declaration at line //3 would link with the declaration at line //1. But because the declaration with internal linkage is hidden, //3 is given external linkage, resulting in a linkage conflict.end example]

Date: 2003-10-15.00:00:00

Notes from October 2003 meeting:

We agree that this is an error. We propose to leave the example but change the comment to indicate that line //3 has undefined behavior, and elsewhere add a normative rule giving such a case undefined behavior.

Date: 2017-02-15.00:00:00

[Adopted at the February/March, 2017 meeting.]

An example in 6.6 [basic.link] paragraph 6 creates two file-scope variables with the same name, one with internal linkage and one with external.

  static void f();
  static int i = 0;                       //1
  void g() {
          extern void f();                // internal linkage
          int i;                          //2: i has no linkage
          {
                  extern void f();        // internal linkage
                  extern int i;           //3: external linkage
          }
  }

Is this really what we want? C99 has 6.2.2.7/7, which gives undefined behavior for having an identifier appear with internal and external linkage in the same translation unit. C++ doesn't seem to have an equivalent.

History
Date User Action Args
2018-02-27 00:00:00adminsetstatus: review -> c++17
2017-02-06 00:00:00adminsetmessages: + msg5744
2017-02-06 00:00:00adminsetmessages: + msg5743
2017-02-06 00:00:00adminsetstatus: drafting -> review
2006-11-05 00:00:00adminsetmessages: + msg1413
2006-11-05 00:00:00adminsetstatus: review -> drafting
2005-10-22 00:00:00adminsetmessages: + msg1229
2005-10-22 00:00:00adminsetstatus: drafting -> review
2003-11-15 00:00:00adminsetmessages: + msg930
2003-11-15 00:00:00adminsetstatus: open -> drafting
2003-07-02 00:00:00admincreate