块范围链接 C 标准

Posted

技术标签:

【中文标题】块范围链接 C 标准【英文标题】:Block scope linkage C standard 【发布时间】:2011-11-06 13:59:14 【问题描述】:

以下标识符没有链接: 声明为对象或函数以外的任何标识符;声明为函数参数的标识符; 不使用存储类说明符 extern 声明的对象的块范围标识符


    static int a; //no linkage

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


    static int a; //no linkage
    extern int a; //a should get external linkage, no?

GCC 错误:没有链接的后续声明的外部声明

谁能解释我为什么会出现这个错误?

谢谢

【问题讨论】:

可能是语义,“指定无链接”与“指定'无链接'”。在这种情况下,自动升级听起来很疯狂。 我不明白其中的区别。你能详细说明一下吗? 【参考方案1】:

您的假设是正确的:a 的第二个声明具有外部链接。但是,您会收到错误,因为您的代码违反了 §6.7 中的约束:

3 如果标识符没有链接,则不应超过一个 标识符的声明(在声明符或类型说明符中) 相同的范围和相同的名称空间,除了标签 在 6.7.2.3 中指定。

也就是说,一旦您将a 声明为没有链接,就不能在同一范围内再次重新声明它。


调用此规则的一个有效示例是:

int a = 10;  /* External linkage */

void foo(void)

    int a = 5;  /* No linkage */

    printf("%d\n", a);    /* Prints 5 */

    
        extern int a;  /* External linkage */

        printf("%d\n", a);    /* Prints 10 */
    

【讨论】:

你能给我一个有效的例子吗:如果前面的声明没有指定链接,那么标识符有外部链接。我想不出来。【参考方案2】:

如果前面的声明没有指定链接

意思

如果先前的声明未指定链接符号

而不是

如果先前的声明指定它没有链接

这是令人困惑和模棱两可的;不是编写标准的通常方式...

【讨论】:

您可以删除静态,错误仍然存​​在。块范围内的静态不会更改链接,只会更改存储持续时间。在文件范围内,它确实会更改链接,但不会更改存储持续时间(始终是静态的)。 c. 中的另一个歧义。 你错了;预期的意思是最后一个,正如它所写的那样。无论如何,它与问题无关。

以上是关于块范围链接 C 标准的主要内容,如果未能解决你的问题,请参考以下文章

ANSI C 标准组合的类型字长和范围

C语言试题186之读取范围在1和标准输入读取的size之前每个数据出现的次数

INDEX MATCH 根据日期范围和名称标准返回多个结果

哪个标准范围适用于C#8中的数组和字符串?

范围和链接有啥区别?

C语言试题186之读取范围在1和标准输入读取的size之前每个数据出现的次数