Joh*_*itb 6 c++ static extern linkage
我有几个关于以下变量的链接的问题.通过C++ 03的7.1.1/7和编译器(Comeau,Clang和GCC)的实例,我得到了以下链接类型:
首先static
,然后extern
static int a; // (a)
extern int a; // (b) valid, 'a' still internal
Run Code Online (Sandbox Code Playgroud)
根据第3.5节,我很清楚:(a)意味着内部联系.并且(b)也暗示内部链接,因为名称"a"被声明为静态(通过(a)).
首先extern
,然后static
extern int b; // (c)
static int b; // (d) invalid!
Run Code Online (Sandbox Code Playgroud)
首先,(c)意味着外部联系.但是(d)意味着内部联系,因为名称"b"被(d)声明为静态.根据7.1.1/7,这是无效的,因为隐含的联系不一致.
首先const
,然后extern
const double pi1 = 3.14; // (e)
extern const double pi1; // (f) valid and 'pi1' is internal
Run Code Online (Sandbox Code Playgroud)
首先,(e)意味着内部联系,因为它是常量,既没有声明明确的外部,也没有先前隐含的外部联系.并且(f)应该暗示extern链接并且是一个错误,因为它明确地声明了extern这个名字,但是编译器将它保持在内部!为什么这样? 那是我的问题.
首先extern
,然后const
extern const double pi2; // (g)
const double pi2 = 3.14; // (h) valid and 'pi2' is external
Run Code Online (Sandbox Code Playgroud)
现在,(g)意味着外部联系,因为我们明确宣布了extern.(h)也暗示外部联系,因为(g)明确宣布外部联系.
我已经通过以下模板实验性地找到了3和4的链接(第二个参数需要具有外部链接)
template<typename T, T&> struct ensure { };
ensure<const double, pi1> e1; // failed
ensure<const double, pi2> e2; // succeeded
Run Code Online (Sandbox Code Playgroud)
摘要:与查尔斯贝利的讨论结果非常富有成果,并表明有两种可能的解释3.5/3
,其中重要的要点是
具有命名空间作用域(3.3.5)的名称具有内部链接(如果它的名称)
- 显式声明为const的对象或引用,既未显式声明为extern,也未声明为具有外部链接;
如果我们看一下(f)
,那么这两种解释会得出不同的结论,如下所示
第一个解释说明了pi1
已宣布const
但也已宣布extern
.因此变量具有外部联系.
第二种解释解释了"声明"的出现以引用同一声明.通过这种方式,它意味着它被声明const
,但不是extern const
.我们注意到这(e)
是宣布const
而不是extern const
,因此我们提供pi1
内部联系.
现在什么解释是正确的?我无法从这个措辞中确定,但编译器似乎是第二种解释.特别是,如果我们采用第一种解释,那么最后引用的部分3.5/3
将是多余的,因为没有有效的场景,其中将声明名称const
并且先前使用外部链接声明但没有明确的extern
.
const double pi1 = 3.14; // (e)
extern const double pi1; // (f) valid and 'pi1' is internal
Run Code Online (Sandbox Code Playgroud)
我的解释如下。在考虑名称的链接时,我们会考虑先前的声明以及此时在解析中解释的声明。这就是为什么static int a; extern int a;
可以,但extern int b; static int b;
不行。
在遇到第一个声明时,我们注意到它pi1
是显式声明的const
,但既没有显式声明extern
也没有先前声明为具有外部链接。这与 3.5/2 的选项之一匹配,因此pi1
具有内部链接。
在遇到第二个声明时,我们询问的是显式声明但既没有显式声明也没有[...等等...]pi1
的对象的名称。我认为这是因为它是在(e)点如此声明的。当然,它并不是在任何地方都以这种方式声明的,但是当我们考虑声明时,以同样的方式声明对象的名称,即使它没有在任何地方都被声明。对我来说,这意味着声明 (f) 并不意味着与声明 (e) 不同的链接。const
extern
a
static
extern int a;
static
归档时间: |
|
查看次数: |
1910 次 |
最近记录: |