内部和无联系之间的区别

时间:2014-07-21 12:13:43

标签: c++ c scope linkage

请参阅同一翻译单元中的以下代码:

static int global_var; // file scope in C and global namespace scope in C++
                       // internal linkage
void f(void)
{
    static int local_var; // block scope in C and local scope in C++
                          // no linkage 
}

我的理解是这样的:

  • 我可以从翻译单元的任何地方参考 global_var ,因为它具有全局范围。
  • 我只能在函数 f 中引用 local_var ,因为它具有本地范围。

我的问题:

  1. 两个变量与链接有什么区别?
  2. 您能否提供一个示例,其中内部无链接有所不同,差异不仅来自范围?
  3. 修改

    在James Kanze的回答和评论之后,我现在能够构建一个示例,显示内部和无链接属性之间的区别:

    static int i; // definition
                  // static storage
                  // internal linkage
    
    void f(void)
    {
        extern int i; // declaration
                      // refers to the static i at file scope
                      // note that even though the specifier is extern
                      // its linkage is intern (this is legal in both C/C++)
        {
            int i; // definition
                   // automatic storage
                   // no linkage
        }
    }
    


    有些文章在解释所涉及的概念方面做得很好:
    - Scope regions in C and C++
    - Storage class specifiers and storage duration
    - Linkage in C and C++

3 个答案:

答案 0 :(得分:8)

第一:除了类型,变量还有另外三个 特点:联系,范围和寿命。这四个 属性是一种正交的,但是以它们的方式链接 用语言表达,并以某种方式进行互动。

关于联动:联系确实影响了符号 正在被宣布,而不是对象本身。如果没有 链接,符号的所有声明绑定到不同的 对象,例如:

int
func()
{
    int i;
    {
        int i;
    }
}

符号i没有链接,两个符号i被绑定 到两个不同的实体。一般来说,局部变量 (在块作用域中声明的变量)和函数参数有 没有联系,无论其类型和寿命如何。

内部和外部的联系是相似的,在那里重复 符号的声明绑定到同一个实体:internal 链接仅在翻译单元内绑定,外部交叉 整个计划。所以给出:

static int i;   //  internal linkage...

在多个翻译单元中,i绑定到单独的实体 在每个翻译单元。没有静电,你有外在的 链接,并且所有i都绑定到同一个实体。

请注意,这仅适用于命名空间范围; 所有实体 哪些是非本地类的成员有外部联系。

这种类型有影响:变量是const 隐含地有内部联系:

int const i = 42;    //  same as static int const i...
extern int const j = 42;    //  external linkage.

最后,所有绑定到同一实体的声明都必须 声明它具有相同的类型。如果您违反此规则 单个翻译单位(例如:

extern int i;
//   ...
double i;

在相同的命名空间范围内),然后编译器应该抱怨。 如果两个声明在不同的翻译单元中, 然而,它是未定义的行为,谁知道会发生什么 发生。 (从理论上讲,链接器可能会抱怨,但大多数人都不会抱怨。)

编辑:

另外一点:联系由第一个决定 声明可以指实体。所以,如果我写:

static int i;

void
func()
{
    extern int i;
}

两个i都指向具有内部链接的同一实体。 (为什么一个人会写第二个宣言超出我的范围, 但这是合法的。)

答案 1 :(得分:0)

通常static变量具有内部链接。您无法访问另一个文件中的static变量或函数(在多个文件编译情况下),因为它的范围仅限于此文件(内部链接)。 通常,autoregister变量没有关联。


正如我上面所说autoregister变量没有联系。您无法在全局范围内声明这些变量。 static变量具有内部链接,范围基于声明,但不能在另一个文件中访问。 extern变量具有外部链接,可以在另一个文件中访问这些变量。

有关详情,请参阅Storage classes

答案 2 :(得分:0)

可以从同一个编译单元中的global_var访问

void g(),这就是区别。