c - 外部 block 作用域变量的链接,C

标签 c extern linkage

C标准说:

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,31) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.



不清楚的是,要考虑的先前标识符是否必须具有相同的类型(注意: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?
    }
}

我尝试使用不同的编译器对其进行测试,但似乎链接主题不是非常团结的主题。

最佳答案

C 为其所有全局变量使用平面 namespace 。与 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 将链接正常,但会产生未定义的行为。

关于c - 外部 block 作用域变量的链接,C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38941497/

相关文章:

c++ - 删除 constexpr 会改变链接吗?

c - recvfrom() 函数不起作用

c - Pset4 (cs50) 恢复无法正常工作。它可以编译,但不能恢复超过 2 个 jpeg。检查 JPEG 签名是否有问题?

c++ - 查询内存位置

c - 外部存储类的理解

c - C中const的外部链接

c - 确定 `_Thread_local` 标识符链接的正式方法是什么?

c - 如何从输入文件中分离/解码二进制字符串? (C)

c - c语言中的外部和全局

c++ - 在库中包含具有外部 C 链接的函数