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".