如何在块范围内声明具有内部链接的标识符,而无需事先声明该标识符且某些链接可见?

Posted

技术标签:

【中文标题】如何在块范围内声明具有内部链接的标识符,而无需事先声明该标识符且某些链接可见?【英文标题】:How to declare identifier with internal-linkage in block-scope without prior declaration of that identifier with some linkage being visible? 【发布时间】:2016-04-30 11:54:43 【问题描述】:

考虑一下:

#include <stdio.h>

static int b;

int main()

    
        int b;

        
            extern int b;

            b = 2;
        
    

    printf("%d", b);

这里根据定义,赋值为 2 的标识符“b”必须是具有外部链接的标识符。但是由于某种原因,“clang”C 编译器没有报错,这段代码的输出是“2”。

我假设这是因为 C 标准中的 $6.2.2.4 点:

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

因为前面的可见声明没有指定链接('int b')。

无论如何,我怎样才能在赋值之前进行声明以引用具有内部链接的标识符(而不是具有外部链接的标识符)。

编辑:我看到这个例子是 UB 但这并没有改变我的问题。

【问题讨论】:

请问那次投反对票的原因是什么? 【参考方案1】:

您的程序有undefined behaviour。您不能在同一范围内拥有具有内部和外部链接的标识符。

C11, §6.2.3, 4

如果在一个翻译单元中,相同的标识符出现在两个 内部和外部链接,行为未定义。

【讨论】:

那怎么可能不是一个呢? 他们不可能合一。对同一标识符同时拥有内部 外部链接是没有意义的(标准说它是未定义的)。 int b;(在main() 内的外部块内)没有链接。 extern int b; 声明 b 具有与指定内部链接的 static int b; 冲突的外部链接。 不,我的意思是我的示例程序如何在不删除没有链接的变量的情况下不产生 UB。你没有回答我的问题。 你能详细说明这个“不,我的意思是我的示例程序如何在不删除没有链接的变量的情况下不产生 UB”? 在 OP 中回答我的问题。

以上是关于如何在块范围内声明具有内部链接的标识符,而无需事先声明该标识符且某些链接可见?的主要内容,如果未能解决你的问题,请参考以下文章

关于类型的存储时间和链接

块内声明函数

范围和链接有啥区别?

如何在块中间移动vAxis值

static关键字在命名空间范围内没用吗?

为什么枚举常量没有链接?