外部块范围变量的链接,C

时间:2016-08-14 10:53:14

标签: c extern linkage

C标准说:

  

对于使用存储类说明符extern声明的标识符   可以看到该标识符的先前声明的范围,31)   如果事先声明指定内部或外部联系,则   后面声明中标识符的链接与   在先前声明中指定的联系。如果没有事先声明   可见,或者如果先前的声明指定没有链接,那么   标识符有外部链接。

尚不清楚的是,先前要考虑的标识符是否必须具有相同的类型(注意:C ++标准明确指出“具有相同名称和类型的实体”)。例如:

static int a;   // internal linkage

void f()
{
    float a;      // no linkage, instead of 'int a' we have 'float a'

    {
        extern int a;     // still external linkage? or internal in this case?
        a = 0;            // still unresolved external?
    }
}

我尝试用不同的编译器测试它,但似乎联系主题并不是一个非常团结的主题。

1 个答案:

答案 0 :(得分:2)

C对其所有全局变量使用平面名称空间。与C ++不同,C ++需要链接器注意全局变量的类型(查找名称修改以获取更多信息),C将此要求提供给程序员。

在同一翻译单元内更改链接时,重新声明具有不同类型的变量是错误的。

我将使用你的例子添加一些小的

static int a;   // internal linkage
static int b;   // internal linkage

void f()
{
    float a = 123.25; // this variable shadows static int a
    int b = 321;      // this variable shadows static int b

    { // Open a new scope, so the line below is not an illegal re-declaration
        // The declarations below "un-shadow" static a and b
        extern int a; // redeclares "a" from the top, "a" remains internal
        extern int b; // redeclares "b" from the top, "b" remains internal
        a = 42;       // not an unresolved external, it's the top "a"
        b = 52;       // not an unresolved external, it's the top "b"
        printf("%d %d\n", a, b); // static int a, static int b
    }
    printf("%f %d\n", a, b);     // local float a, int b
}

此示例打印

42 52
123.250000 321

当您在多个翻译单元中更改类型时,C ++会在链接时捕获它,而C将链接正常,但会产生未定义的行为。