Open e48d0f12-b0d3-485a-93ce-75b823b0ccac opened 10 years ago
Some random related findings:
For the related case of
static int i;
struct S {
int i;
static int f() {
extern int i;
return i;
}
};
int main() { return S::f(); }
Clang does reference an external var.
For the original example from comment 0, behaviour of at least Clang 3.2 and 3.3 was to reference an external var, only since 3.4 it references the static var. (But for the above struct-based example, behaviour has consistently been the same ever since at least 3.2.)
How about the sample code below? ICBW, I think that the following sample code is compiled incorrectly with clang 3.4 or later.
#include <iostream>
namespace NS {
int i = 1; // #​1 has external linkage
}
static int i = 2; // #​2 has internal linkage
int main()
{
using NS::i; // It refers to #​1, has external linkage.
//extern int i;
std::cout << i << std::endl; // It refers to #​1, of course.
{
extern int i; // I think it should refer to #​1,
std::cout << i << std::endl; // but it refers to #​2.
}
}
Acoording to 7.3.3 p1, a using-declaration introduces a name as a synomym.
And, according to 3.5 p6, if an declaration is visible and the declared entity has a linkage, an extern
declaration refers to the entity, and it only ignores entities declared outside the innermost enclosing namespace scope.
NS::i
has external linkage, So I think that the extern int i;
should refer to #1
.
FYI, if a comment //extern int i;
is uncommented, it refers to #1
.
Oh... I cannot understand why the issue #426
is disregarded.
In addition, I found 3.3.1 p4's note.
I think that it considers main.cc as ill-formed because #1
(has internal linkage) and #3
(has external linkage) refer to the different entities (3.5 p9) but has same name in a single declarative region (global namespace).
Per the current resolution of http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#426, we should reject this code. (Per the former resolution, the example has undefined behavior.)
Extended Description
I think that the following sample code should return
4
, but clang returns1
.According to C++11 standard 3.5 p6,
#3
should refer to#4
because#1
is not visible from the point#3
.