全局变量初始化顺序?

时间:2022-01-06 19:43:14
全局变量
int a = 5;
int b = a;
如果a, 和b定义在同一个文件里,那没什么问题, 结果b等于5.
如果a和b定义在不同文件里,能不能保证b也等于5,就是说能不能保证a先初始化.当遇到b = a时
,会不会先去初始化a呀?
谢谢

16 个解决方案

#1


自己实验一下就可以了

#2


你的全局定义, 根据定义规则, 如果 在b以前, a没有定义, 那么这个是会出错的 !
也就是说, b要么等于 5, 要么是程序出错 ...

#3


如果在不同文件里面,那你INT B=A前难道不需要用关键词EXTERN来告诉编译器这个A要从外部来吗?

#4


不能保证,事实上,除了在同一个文件定义的全局对象的初始化
是按照定义次序来进行的之外,其他全局或静态变量之间的初始
化次序没有任何保障。解决这种问题的方法是不直接使用全局变
量,而改用一个包装函数来访问,例如
int get_a()
{
    static int a = 5;
    return a;
}
int get_b()
{
    static int b = get_a();
    return b;
}

这样的话,无论get_a和get_b是否定义在同一个文件中,get_b总是
能够返回正确的结果,原因在于,函数内部的静态变量是在第一次
访问的时候来初始化。

#5


同意楼上!

#6


记住了,最好,千万不要写出和编译顺序相关的程序来。

比如你问全局变量的初始化顺序这样的问题。。。

#7


mark

#8


支持二楼说法~~
假如是在两个不同的文件里面先定义了a,然后再定义b那就没有问题~~
反之,编译器则会报错~~

#9


关于全局变量的初始化,C语言和C++是有区别的。

在C语言中,只能用常数对全局变量进行初始化,否则编译器会报错。

在C++中,如果在一个文件中定义了int a = 5;要在另一个文件中定义int b = a;的话,前面必须对a进行声明:extern int a;否则编译不通过. 即使是这样,int b = a;这句话也是分两步进行的:在编译阶段,编译器把b当作是未初始化数据而将它初始化为0;在执行阶段,在main被执行前有一个全局对象的构造过程,int b = a;被当作是int型对象b的拷贝初始化构造来执行。

其实,准确地说,在C++中全局对象、变量的初始化是独立的,如果不是象int a = 5;这样的已初始化数据,那么就是象b这样的未初始化数据。

而C++中全局对象、变量的构造函数调用顺序是跟声明有一定关系的,即在同一个文件中先声明的先调用。对于不同文件中的全局对象、变量,它们的构造函数调用顺序是未定义的,取决于具体的编译器。

#10


同一楼上的观点。
另外对 GuanXP兄弟的官邸有些疑问?
不能保证,事实上,除了在同一个文件定义的全局对象的初始化
是按照定义次序来进行的之外,其他全局或静态变量之间的初始
化次序没有任何保障。解决这种问题的方法是不直接使用全局变
量,而改用一个包装函数来访问,例如
int get_a()
{
    static int a = 5;
    return a;
}
int get_b()
{
    static int b = get_a();
    return b;
}

这样的话,无论get_a和get_b是否定义在同一个文件中,get_b总是
能够返回正确的结果,原因在于,函数内部的静态变量是在第一次
访问的时候来初始化。
对于函数内部的静态变量的初始化也应该在编译阶段就完成了,而不是在第一次调用时

#11


GuanXP(不能用于登录)正解
.......................................

任何时候,如果在不同的被编译单元中定义了 "非局部静态对象" ,并且这些对象的正确行为依赖于它们被初始化的某一特定顺序,就会产生问题.你绝对无法控制不同被编译单元中非局部静态对象的初始化顺序.
对于函数中的静态对象(即"局部" 静态对象)它们在函数调用过程中初次碰到对象的定义时被初始化..

#12


int&get_a()
{
    static int a = 5;
    return a;
}
.........
int b=get_a();

#13


你发错地盘了,这里是C,不是C++,C里面不允许使用非常量来初始化全局/静态变量

转C++

#14


这个要依赖编译器~~

#15


关于C++中局部静态对象/变量的初始化想说两句:
    1、这种变量的存储是在编译时就分配好了的,对于编译阶段就能确定初值的对象,比如static int x=2,编译器会把它们放到.data区中;对于没有给初值或编译阶段不能确定初值的对象,比如static int x,或者是需要调用构造函数的对象,比如static A a = 8, 编译器统一把它们当作是未初始化数据来处理,将其所占内存区统统置为0并放在.bss区中;
    2、"在函数调用过程中初次碰到(局部静态)对象的定义时",准确地说是该对象的构造函数被调用,如果须要的话。

#16


多谢
没想到这么多人对C,C++都很熟悉

#1


自己实验一下就可以了

#2


你的全局定义, 根据定义规则, 如果 在b以前, a没有定义, 那么这个是会出错的 !
也就是说, b要么等于 5, 要么是程序出错 ...

#3


如果在不同文件里面,那你INT B=A前难道不需要用关键词EXTERN来告诉编译器这个A要从外部来吗?

#4


不能保证,事实上,除了在同一个文件定义的全局对象的初始化
是按照定义次序来进行的之外,其他全局或静态变量之间的初始
化次序没有任何保障。解决这种问题的方法是不直接使用全局变
量,而改用一个包装函数来访问,例如
int get_a()
{
    static int a = 5;
    return a;
}
int get_b()
{
    static int b = get_a();
    return b;
}

这样的话,无论get_a和get_b是否定义在同一个文件中,get_b总是
能够返回正确的结果,原因在于,函数内部的静态变量是在第一次
访问的时候来初始化。

#5


同意楼上!

#6


记住了,最好,千万不要写出和编译顺序相关的程序来。

比如你问全局变量的初始化顺序这样的问题。。。

#7


mark

#8


支持二楼说法~~
假如是在两个不同的文件里面先定义了a,然后再定义b那就没有问题~~
反之,编译器则会报错~~

#9


关于全局变量的初始化,C语言和C++是有区别的。

在C语言中,只能用常数对全局变量进行初始化,否则编译器会报错。

在C++中,如果在一个文件中定义了int a = 5;要在另一个文件中定义int b = a;的话,前面必须对a进行声明:extern int a;否则编译不通过. 即使是这样,int b = a;这句话也是分两步进行的:在编译阶段,编译器把b当作是未初始化数据而将它初始化为0;在执行阶段,在main被执行前有一个全局对象的构造过程,int b = a;被当作是int型对象b的拷贝初始化构造来执行。

其实,准确地说,在C++中全局对象、变量的初始化是独立的,如果不是象int a = 5;这样的已初始化数据,那么就是象b这样的未初始化数据。

而C++中全局对象、变量的构造函数调用顺序是跟声明有一定关系的,即在同一个文件中先声明的先调用。对于不同文件中的全局对象、变量,它们的构造函数调用顺序是未定义的,取决于具体的编译器。

#10


同一楼上的观点。
另外对 GuanXP兄弟的官邸有些疑问?
不能保证,事实上,除了在同一个文件定义的全局对象的初始化
是按照定义次序来进行的之外,其他全局或静态变量之间的初始
化次序没有任何保障。解决这种问题的方法是不直接使用全局变
量,而改用一个包装函数来访问,例如
int get_a()
{
    static int a = 5;
    return a;
}
int get_b()
{
    static int b = get_a();
    return b;
}

这样的话,无论get_a和get_b是否定义在同一个文件中,get_b总是
能够返回正确的结果,原因在于,函数内部的静态变量是在第一次
访问的时候来初始化。
对于函数内部的静态变量的初始化也应该在编译阶段就完成了,而不是在第一次调用时

#11


GuanXP(不能用于登录)正解
.......................................

任何时候,如果在不同的被编译单元中定义了 "非局部静态对象" ,并且这些对象的正确行为依赖于它们被初始化的某一特定顺序,就会产生问题.你绝对无法控制不同被编译单元中非局部静态对象的初始化顺序.
对于函数中的静态对象(即"局部" 静态对象)它们在函数调用过程中初次碰到对象的定义时被初始化..

#12


int&get_a()
{
    static int a = 5;
    return a;
}
.........
int b=get_a();

#13


你发错地盘了,这里是C,不是C++,C里面不允许使用非常量来初始化全局/静态变量

转C++

#14


这个要依赖编译器~~

#15


关于C++中局部静态对象/变量的初始化想说两句:
    1、这种变量的存储是在编译时就分配好了的,对于编译阶段就能确定初值的对象,比如static int x=2,编译器会把它们放到.data区中;对于没有给初值或编译阶段不能确定初值的对象,比如static int x,或者是需要调用构造函数的对象,比如static A a = 8, 编译器统一把它们当作是未初始化数据来处理,将其所占内存区统统置为0并放在.bss区中;
    2、"在函数调用过程中初次碰到(局部静态)对象的定义时",准确地说是该对象的构造函数被调用,如果须要的话。

#16


多谢
没想到这么多人对C,C++都很熟悉