【问题标题】:Two variables in global namespace, same name allowed, how? [duplicate]全局命名空间中的两个变量,允许同名,如何? [复制]
【发布时间】:2018-02-18 15:44:13
【问题描述】:
/*How does this code compiles and executes in C?*/
#include <stdio.h>
int x= 9; //Varaible initialization
int x; //Variable declaration, same name

int main(void) {
    printf("%d", x); //output: 9
    return 0;
}

使用相同变量进行编译时应该会出错。代码是怎么编译的?

【问题讨论】:

    标签: c


    【解决方案1】:

    您可以从standard 6.9.2p2 了解这一点——这被称为暂定定义。

    来自here

    暂定定义是没有初始化器的外部声明,或者没有存储类说明符或带有说明符 static。

    暂定定义是一个声明,可能会或可能不会作为定义。 如果在同一个翻译单元中更早或更晚地发现了一个实际的外部定义,那么这个暂定定义就只是一个声明。

    int i1 = 1;     // definition, external linkage
    int i1;         // tentative definition, acts as declaration because i1 is defined.
    

    因此,从这两个参考中可以清楚地看出,第二个只是归结为标准词上的声明或有效的暂定定义,它采用的值是分配的 1

    Sane 为您服务,x 的值为 9

    【讨论】:

      【解决方案2】:

      您可以根据需要多次声明一个全局变量或函数。但是你必须只有一个定义。第一行给变量赋值,所以它是一个声明和定义的结合。第二行没有赋值,所以只是声明。

      【讨论】:

        【解决方案3】:

        在全局范围内,可以有两个具有相同名称的变量,但一个应该是un-intialized(weak symbol),另一个应该是initialized(strong symbol)

        int x= 9; /* strong symbol i.e declaration with definition*/
        int x; /* weak symbol i.e only declaration */
        

        在两者中进行选择时,优先考虑两个strong 符号。

        注意:编译器不允许一次有two strong symbol,那将是一个re-definition 的变量。

        【讨论】:

        • 我认为它确实允许 2 个弱定义。
        • 同意@PaulOgilvie
        【解决方案4】:

        第二个不是定义。这是一个声明

        来自ISO C standard draft N1570, Section 6.9.2

        1 如果对象标识符的声明具有文件范围和初始化程序,则该声明是标识符的外部定义

        2 一个对象的标识符声明构成一个暂定定义 em>. 如果翻译单元包含一个或多个标识符的暂定定义,并且该翻译单元不包含该标识符的外部定义,则该行为与翻译单元包含该标识符的文件范围声明完全相同标识符,复合类型为翻译单元末尾,初始化器等于 0。

        所以当你写的时候

        int x;
        

        在文件范围内,它不一定是定义。这是一个声明,可以重复。

        这在 C 中称为暂定定义。查看更多hereherehere

        【讨论】:

        • 然而,如果你删除了第一个定义,第二个就会变成一个定义。奇怪的是,C 是非本地的。
        猜你喜欢
        • 2012-03-13
        • 1970-01-01
        • 2011-03-25
        • 2021-03-21
        • 2014-02-17
        • 2011-08-31
        • 2017-01-04
        • 1970-01-01
        • 2016-04-08
        相关资源
        最近更新 更多