C++难道没有规定,全局变量的初始化顺序?没有自动调整的机制?编译器有BUG?

时间:2021-07-17 19:40:05
例子:
********************file1.cpp

int a1 = 1191;

extern int b2;
int b3 = b2 + 1;


********************file2.cpp

extern int a1;
int a2 = a1 + 1;

extern int b1;
int b2 = b1 + 1;


********************file3.cpp

extern int a2;
int a3 = a2 + 1;

int b1 = 2212;



********************main.cpp

extern int a3;
extern int b3;
int main()
{
std::cout<<a3<<std::endl;
std::cout<<b3<<std::endl;
}






猜猜上面的a3和b3的输出结果,是否正确?结果是有问题的。




43 个解决方案

#1


没有规定,全局变量的初始化顺序

#2


那上面的代码,不能正确初始化,没有办法解决?

引用 1 楼 ganpengjin1 的回复:
没有规定,全局变量的初始化顺序

#3


引用 2 楼 u013486147 的回复:
那上面的代码,不能正确初始化,没有办法解决?

Quote: 引用 1 楼 ganpengjin1 的回复:

没有规定,全局变量的初始化顺序

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。

#4


这种代码有什么问题?违反了C++的什么规定?还是什么原则?

引用 3 楼 luciferisnotsatan 的回复:
谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。

#5


引用 4 楼 u013486147 的回复:
这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

#6


导致不正确性的根源是?

引用 5 楼 derekrose 的回复:
Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

#7


引用 5 楼 derekrose 的回复:
Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

不确定的行为会导致,目前程序跑得没问题,但之后做了些变动,如升级/更换的编译器,导致出了莫名奇妙的问题。结果一堆人排查了半天,原来是lz这代码造成的。

#8


引用 6 楼 u013486147 的回复:
导致不正确性的根源是?

Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

C++对这些不做规定,是为了让编译器能够更好的优化代码。

#9


引用 2 楼 u013486147 的回复:
那上面的代码,不能正确初始化,没有办法解决?

Quote: 引用 1 楼 ganpengjin1 的回复:

没有规定,全局变量的初始化顺序

你在定义的时候初始化一下呗。

#10


引用 7 楼 luciferisnotsatan 的回复:
Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

不确定的行为会导致,目前程序跑得没问题,但之后做了些变动,如升级/更换的编译器,导致出了莫名奇妙的问题。结果一堆人排查了半天,原来是lz这代码造成的。


楼主应该是学生吧。

#11


目测违反了潜规则~~~~~~~~~

#12


那全局变量的使用,应该遵循什么原则?
或是没有原则?你有没有好的经验传授一下?

引用 8 楼 luciferisnotsatan 的回复:
Quote: 引用 6 楼 u013486147 的回复:

导致不正确性的根源是?

Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

C++对这些不做规定,是为了让编译器能够更好的优化代码。

#13


你要记住,工作中写的代码,是要给别人看的,也要给6个月后的你看的。
别说不确定的行为,就算是确定的,最好也写的清晰点。不然以后要花不少时间去搞懂当初写的这段代码是怎么运作的。

#14


不是初始化了吗?

引用 9 楼 ganpengjin1 的回复:
Quote: 引用 2 楼 u013486147 的回复:

那上面的代码,不能正确初始化,没有办法解决?

Quote: 引用 1 楼 ganpengjin1 的回复:

没有规定,全局变量的初始化顺序

你在定义的时候初始化一下呗。

#15


这只是随便写写的代码,是想测试一下全局变量的初始化的一些结果。

我上面的代码,为什么说是不确定行为?

extern int a;
int b = a;       //这行就属于不确定行为?

因为b没有初始化为一个常量?不是很明白,哪里是不确定行为。。

引用 13 楼 luciferisnotsatan 的回复:
你要记住,工作中写的代码,是要给别人看的,也要给6个月后的你看的。
别说不确定的行为,就算是确定的,最好也写的清晰点。不然以后要花不少时间去搞懂当初写的这段代码是怎么运作的。

#16


引用 12 楼 u013486147 的回复:
那全局变量的使用,应该遵循什么原则?
或是没有原则?你有没有好的经验传授一下?

Quote: 引用 8 楼 luciferisnotsatan 的回复:

Quote: 引用 6 楼 u013486147 的回复:

导致不正确性的根源是?

Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

C++对这些不做规定,是为了让编译器能够更好的优化代码。

经验就是,别在全局里写这种代码。
extern int a1;
int a2 = a1 + 1;
 
extern int b1;
int b2 = b1 + 1;

如过非要给全局做初始化,那就做个init函数,来赋值

#17


我刚才封装了函数来初始化,还是有问题啊,结果还是不正确。

我现在的问题是:全局变量的初始化,需要依赖其他全局变量。

这里可能存在一些全局变量初始化的先后顺序问题,觉得比较难搞。



引用 16 楼 luciferisnotsatan 的回复:
Quote: 引用 12 楼 u013486147 的回复:

那全局变量的使用,应该遵循什么原则?
或是没有原则?你有没有好的经验传授一下?

Quote: 引用 8 楼 luciferisnotsatan 的回复:

Quote: 引用 6 楼 u013486147 的回复:

导致不正确性的根源是?

Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

C++对这些不做规定,是为了让编译器能够更好的优化代码。

经验就是,别在全局里写这种代码。
extern int a1;
int a2 = a1 + 1;
 
extern int b1;
int b2 = b1 + 1;

如过非要给全局做初始化,那就做个init函数,来赋值

#18


引用 13 楼 luciferisnotsatan 的回复:
你要记住,工作中写的代码,是要给别人看的,也要给6个月后的你看的。
别说不确定的行为,就算是确定的,最好也写的清晰点。不然以后要花不少时间去搞懂当初写的这段代码是怎么运作的。


引用 14 楼 u013486147 的回复:
不是初始化了吗?

Quote: 引用 9 楼 ganpengjin1 的回复:

Quote: 引用 2 楼 u013486147 的回复:

那上面的代码,不能正确初始化,没有办法解决?

Quote: 引用 1 楼 ganpengjin1 的回复:

没有规定,全局变量的初始化顺序

你在定义的时候初始化一下呗。

这样没节操的代码,完全是给自己找麻烦,自己都不确定的代码,还指望别人看得懂?
深深蛋疼。

--------
你说初始化了,你确实是初始化了,但是你能告诉我是按照哪个顺序初始的么?显然不能确定,也没有规定。

#19



给你说下吧:
int a1 = 1191;
 
extern int b2;
int b3 = b2 + 1;

好比这个,你确定是b2完之后再出初始化b3么,没人能够保证。

#20


可以用函数的静态变量来 处理初始化顺序

int get_a()
{
static int a = 3;
return a;
}

但是在多线程下得小心
get_a() 在2个线程下同时调用
若 a 的类型是个结构体  可能会出现 a 没完全初始化 
就被另一个线程返回了
不过只初始化一次是有保证的

#21


就是初始化顺序的顺序问题。

我想解决的,正是:

假如全局变量A的初始化,依赖于全局变量B的初始值。

我有什么方法,可以确保全局变量B,必先会被初始化?



引用 18 楼 ganpengjin1 的回复:
Quote: 引用 13 楼 luciferisnotsatan 的回复:

你要记住,工作中写的代码,是要给别人看的,也要给6个月后的你看的。
别说不确定的行为,就算是确定的,最好也写的清晰点。不然以后要花不少时间去搞懂当初写的这段代码是怎么运作的。


引用 14 楼 u013486147 的回复:
不是初始化了吗?

Quote: 引用 9 楼 ganpengjin1 的回复:



Quote: 引用 2 楼 u013486147 的回复:

那上面的代码,不能正确初始化,没有办法解决?

Quote: 引用 1 楼 ganpengjin1 的回复:

没有规定,全局变量的初始化顺序

你在定义的时候初始化一下呗。

这样没节操的代码,完全是给自己找麻烦,自己都不确定的代码,还指望别人看得懂?
深深蛋疼。

--------
你说初始化了,你确实是初始化了,但是你能告诉我是按照哪个顺序初始的么?显然不能确定,也没有规定。

#22


你谈到了多线程问题,我刚好就是为了解决多线程的一些问题,而需要初始化一些全局变量。


引用 20 楼 wangjunsheng 的回复:
可以用函数的静态变量来 处理初始化顺序

int get_a()
{
static int a = 3;
return a;
}

但是在多线程下得小心
get_a() 在2个线程下同时调用
若 a 的类型是个结构体  可能会出现 a 没完全初始化 
就被另一个线程返回了
不过只初始化一次是有保证的

#23


就是初始化顺序的顺序问题。

我想解决的,正是:

假如全局变量A的初始化,依赖于全局变量B的初始值。

我有什么方法,可以确保全局变量B,必先会被初始化?

既然是全局,那么你的定义就放一起定义,要用到的地方extern 就好了。

能不用全部变量尽量不要用。

#24


我的题目正好就是问这个问题啊。


引用 23 楼 ganpengjin1 的回复:
就是初始化顺序的顺序问题。

我想解决的,正是:

假如全局变量A的初始化,依赖于全局变量B的初始值。

我有什么方法,可以确保全局变量B,必先会被初始化?

既然是全局,那么你的定义就放一起定义,要用到的地方extern 就好了。

能不用全部变量尽量不要用。


引用 19 楼 ganpengjin1 的回复:
给你说下吧:
int a1 = 1191;
 
extern int b2;
int b3 = b2 + 1;

好比这个,你确定是b2完之后再出初始化b3么,没人能够保证。

#25


对于C语言和C++语言来说,没有任何办法能解决楼主关于全局变量初始化依赖的问题。

是没有任何办法,而不是假设什么就能解决。

#26


引用 22 楼 u013486147 的回复:
你谈到了多线程问题,我刚好就是为了解决多线程的一些问题,而需要初始化一些全局变量。


Quote: 引用 20 楼 wangjunsheng 的回复:

可以用函数的静态变量来 处理初始化顺序

int get_a()
{
static int a = 3;
return a;
}

但是在多线程下得小心
get_a() 在2个线程下同时调用
若 a 的类型是个结构体  可能会出现 a 没完全初始化 
就被另一个线程返回了
不过只初始化一次是有保证的


多线程的话
在别的线程启动前  由主线程  主动调用初始化  如
void init()
{
    int n = get_a(); // init get_a() 中的 static int a;
    ...
}

函数的静态变量可以解决变量初始化顺序的问题
试试吧

#27


把所有全局变量都改成函数吧.

//int g = 3;
//declaration
int* g();
//implementation
int* g()
{
  static int g = 3;
  return &g;
}

#28


引用 楼主 u013486147 的回复:
例子:
********************file1.cpp

int a1 = 1191;

extern int b2;
int b3 = b2 + 1;


********************file2.cpp

extern int a1;
int a2 = a1 + 1;

extern int b1;
int b2 = b1 + 1;


********************file3.cpp

extern int a2;
int a3 = a2 + 1;

int b1 = 2212;



********************main.cpp

extern int a3;
extern int b3;
int main()
{
std::cout<<a3<<std::endl;
std::cout<<b3<<std::endl;
}






猜猜上面的a3和b3的输出结果,是否正确?结果是有问题的。


C++只保证了同一个文件里的全局变量是按顺序初始化的,不同文件的不保证顺序

#29


但是的确还有一个多线程的问题:

static int g = 3;

这两行代码,有可能两个线程同时执行。





引用 27 楼 mujiok2003 的回复:
把所有全局变量都改成函数吧.


//int g = 3;
//declaration
int* g();
//implementation
int* g()
{
  static int g = 3;
  return &g;
}

#30


全局对象也有多线程竞争访问问题. 
引用 29 楼 u013486147 的回复:
但是的确还有一个多线程的问题:

static int g = 3;

这两行代码,有可能两个线程同时执行。







Quote: 引用 27 楼 mujiok2003 的回复:

把所有全局变量都改成函数吧.


//int g = 3;
//declaration
int* g();
//implementation
int* g()
{
  static int g = 3;
  return &g;
}

#31


《程序员的自我修养——链接、装载与库》
《Windows PE权威指南》

#32


多线程的话,就加锁吧。

#33


不要写依赖于编译顺序的程序。
不过,貌似用pragma编译指令可以有办法规定变量的初始化顺序。

#34


在C里面这代码是Error 多干脆

#35


从编程规范角度, 这些全局变量既然相互关联, 就应该集中在一个源文件中定义, 其他文件用extern引用.

#36


依赖于编译器,初始化顺序只保证同一文件,不同文件,编译器执行不确定。

#37


C++难道没有规定,全局变量的初始化顺序?没有自动调整的机制?编译器有BUG?

#38


引用 17 楼 u013486147 的回复:
我刚才封装了函数来初始化,还是有问题啊,结果还是不正确。

我现在的问题是:全局变量的初始化,需要依赖其他全局变量。

这里可能存在一些全局变量初始化的先后顺序问题,觉得比较难搞。



Quote: 引用 16 楼 luciferisnotsatan 的回复:

Quote: 引用 12 楼 u013486147 的回复:

那全局变量的使用,应该遵循什么原则?
或是没有原则?你有没有好的经验传授一下?

Quote: 引用 8 楼 luciferisnotsatan 的回复:

Quote: 引用 6 楼 u013486147 的回复:

导致不正确性的根源是?

Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

C++对这些不做规定,是为了让编译器能够更好的优化代码。

经验就是,别在全局里写这种代码。
extern int a1;
int a2 = a1 + 1;
 
extern int b1;
int b2 = b1 + 1;

如过非要给全局做初始化,那就做个init函数,来赋值

方法也不难:写一个类,把全局变量的初始化逻辑写在类的构造函数里,然后建立一个该类的全局变量。

#39


楼主如果用VC编译器的话,就用#pragma init_seg(lib)吧

看看这个:
HOW TO: Use #pragma init_seg to Control Static Construction

#40



//dec.h
#ifndef __DEC_H__
#define __DEC_H__
extern a1,a2,a3,b1,b2,b3;
#endif

//dec.cpp
#include "dec.h"
int a1 = 1191;
int a2 = a1 + 1;
int a3 = a2 + 1;
int b1 = 2212;
int b2 = b1 + 1;
int b3 = b2 + 1;

//main.cpp
#include <iostream>
#include "dec.h"
int main()
{
   std::cout<<a3<<std::endl;
   std::cout<<b3<<std::endl;
}

LZ 这样试试吧,既然全局变量有依赖关系,你何必分开来定义,放在一个编译单元里定义不就行了~

#41


引用 40 楼 vipcxj 的回复:

//dec.h
#ifndef __DEC_H__
#define __DEC_H__
extern a1,a2,a3,b1,b2,b3;
#endif

//dec.cpp
#include "dec.h"
int a1 = 1191;
int a2 = a1 + 1;
int a3 = a2 + 1;
int b1 = 2212;
int b2 = b1 + 1;
int b3 = b2 + 1;

//main.cpp
#include <iostream>
#include "dec.h"
int main()
{
   std::cout<<a3<<std::endl;
   std::cout<<b3<<std::endl;
}

LZ 这样试试吧,既然全局变量有依赖关系,你何必分开来定义,放在一个编译单元里定义不就行了~


extern int a1,a2,a3,b1,b2,b3;

笔误,少了个int。

#42


c++定义变量一定要赋初值,不然在运行时时随机赋值的。

#43


晕啊,你仔细想想,如果有顺序的话,这么多的文件,应当按照一个什么样的顺序呢???? C++难道没有规定,全局变量的初始化顺序?没有自动调整的机制?编译器有BUG?

#1


没有规定,全局变量的初始化顺序

#2


那上面的代码,不能正确初始化,没有办法解决?

引用 1 楼 ganpengjin1 的回复:
没有规定,全局变量的初始化顺序

#3


引用 2 楼 u013486147 的回复:
那上面的代码,不能正确初始化,没有办法解决?

Quote: 引用 1 楼 ganpengjin1 的回复:

没有规定,全局变量的初始化顺序

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。

#4


这种代码有什么问题?违反了C++的什么规定?还是什么原则?

引用 3 楼 luciferisnotsatan 的回复:
谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。

#5


引用 4 楼 u013486147 的回复:
这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

#6


导致不正确性的根源是?

引用 5 楼 derekrose 的回复:
Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

#7


引用 5 楼 derekrose 的回复:
Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

不确定的行为会导致,目前程序跑得没问题,但之后做了些变动,如升级/更换的编译器,导致出了莫名奇妙的问题。结果一堆人排查了半天,原来是lz这代码造成的。

#8


引用 6 楼 u013486147 的回复:
导致不正确性的根源是?

Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

C++对这些不做规定,是为了让编译器能够更好的优化代码。

#9


引用 2 楼 u013486147 的回复:
那上面的代码,不能正确初始化,没有办法解决?

Quote: 引用 1 楼 ganpengjin1 的回复:

没有规定,全局变量的初始化顺序

你在定义的时候初始化一下呗。

#10


引用 7 楼 luciferisnotsatan 的回复:
Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

不确定的行为会导致,目前程序跑得没问题,但之后做了些变动,如升级/更换的编译器,导致出了莫名奇妙的问题。结果一堆人排查了半天,原来是lz这代码造成的。


楼主应该是学生吧。

#11


目测违反了潜规则~~~~~~~~~

#12


那全局变量的使用,应该遵循什么原则?
或是没有原则?你有没有好的经验传授一下?

引用 8 楼 luciferisnotsatan 的回复:
Quote: 引用 6 楼 u013486147 的回复:

导致不正确性的根源是?

Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

C++对这些不做规定,是为了让编译器能够更好的优化代码。

#13


你要记住,工作中写的代码,是要给别人看的,也要给6个月后的你看的。
别说不确定的行为,就算是确定的,最好也写的清晰点。不然以后要花不少时间去搞懂当初写的这段代码是怎么运作的。

#14


不是初始化了吗?

引用 9 楼 ganpengjin1 的回复:
Quote: 引用 2 楼 u013486147 的回复:

那上面的代码,不能正确初始化,没有办法解决?

Quote: 引用 1 楼 ganpengjin1 的回复:

没有规定,全局变量的初始化顺序

你在定义的时候初始化一下呗。

#15


这只是随便写写的代码,是想测试一下全局变量的初始化的一些结果。

我上面的代码,为什么说是不确定行为?

extern int a;
int b = a;       //这行就属于不确定行为?

因为b没有初始化为一个常量?不是很明白,哪里是不确定行为。。

引用 13 楼 luciferisnotsatan 的回复:
你要记住,工作中写的代码,是要给别人看的,也要给6个月后的你看的。
别说不确定的行为,就算是确定的,最好也写的清晰点。不然以后要花不少时间去搞懂当初写的这段代码是怎么运作的。

#16


引用 12 楼 u013486147 的回复:
那全局变量的使用,应该遵循什么原则?
或是没有原则?你有没有好的经验传授一下?

Quote: 引用 8 楼 luciferisnotsatan 的回复:

Quote: 引用 6 楼 u013486147 的回复:

导致不正确性的根源是?

Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

C++对这些不做规定,是为了让编译器能够更好的优化代码。

经验就是,别在全局里写这种代码。
extern int a1;
int a2 = a1 + 1;
 
extern int b1;
int b2 = b1 + 1;

如过非要给全局做初始化,那就做个init函数,来赋值

#17


我刚才封装了函数来初始化,还是有问题啊,结果还是不正确。

我现在的问题是:全局变量的初始化,需要依赖其他全局变量。

这里可能存在一些全局变量初始化的先后顺序问题,觉得比较难搞。



引用 16 楼 luciferisnotsatan 的回复:
Quote: 引用 12 楼 u013486147 的回复:

那全局变量的使用,应该遵循什么原则?
或是没有原则?你有没有好的经验传授一下?

Quote: 引用 8 楼 luciferisnotsatan 的回复:

Quote: 引用 6 楼 u013486147 的回复:

导致不正确性的根源是?

Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

C++对这些不做规定,是为了让编译器能够更好的优化代码。

经验就是,别在全局里写这种代码。
extern int a1;
int a2 = a1 + 1;
 
extern int b1;
int b2 = b1 + 1;

如过非要给全局做初始化,那就做个init函数,来赋值

#18


引用 13 楼 luciferisnotsatan 的回复:
你要记住,工作中写的代码,是要给别人看的,也要给6个月后的你看的。
别说不确定的行为,就算是确定的,最好也写的清晰点。不然以后要花不少时间去搞懂当初写的这段代码是怎么运作的。


引用 14 楼 u013486147 的回复:
不是初始化了吗?

Quote: 引用 9 楼 ganpengjin1 的回复:

Quote: 引用 2 楼 u013486147 的回复:

那上面的代码,不能正确初始化,没有办法解决?

Quote: 引用 1 楼 ganpengjin1 的回复:

没有规定,全局变量的初始化顺序

你在定义的时候初始化一下呗。

这样没节操的代码,完全是给自己找麻烦,自己都不确定的代码,还指望别人看得懂?
深深蛋疼。

--------
你说初始化了,你确实是初始化了,但是你能告诉我是按照哪个顺序初始的么?显然不能确定,也没有规定。

#19



给你说下吧:
int a1 = 1191;
 
extern int b2;
int b3 = b2 + 1;

好比这个,你确定是b2完之后再出初始化b3么,没人能够保证。

#20


可以用函数的静态变量来 处理初始化顺序

int get_a()
{
static int a = 3;
return a;
}

但是在多线程下得小心
get_a() 在2个线程下同时调用
若 a 的类型是个结构体  可能会出现 a 没完全初始化 
就被另一个线程返回了
不过只初始化一次是有保证的

#21


就是初始化顺序的顺序问题。

我想解决的,正是:

假如全局变量A的初始化,依赖于全局变量B的初始值。

我有什么方法,可以确保全局变量B,必先会被初始化?



引用 18 楼 ganpengjin1 的回复:
Quote: 引用 13 楼 luciferisnotsatan 的回复:

你要记住,工作中写的代码,是要给别人看的,也要给6个月后的你看的。
别说不确定的行为,就算是确定的,最好也写的清晰点。不然以后要花不少时间去搞懂当初写的这段代码是怎么运作的。


引用 14 楼 u013486147 的回复:
不是初始化了吗?

Quote: 引用 9 楼 ganpengjin1 的回复:



Quote: 引用 2 楼 u013486147 的回复:

那上面的代码,不能正确初始化,没有办法解决?

Quote: 引用 1 楼 ganpengjin1 的回复:

没有规定,全局变量的初始化顺序

你在定义的时候初始化一下呗。

这样没节操的代码,完全是给自己找麻烦,自己都不确定的代码,还指望别人看得懂?
深深蛋疼。

--------
你说初始化了,你确实是初始化了,但是你能告诉我是按照哪个顺序初始的么?显然不能确定,也没有规定。

#22


你谈到了多线程问题,我刚好就是为了解决多线程的一些问题,而需要初始化一些全局变量。


引用 20 楼 wangjunsheng 的回复:
可以用函数的静态变量来 处理初始化顺序

int get_a()
{
static int a = 3;
return a;
}

但是在多线程下得小心
get_a() 在2个线程下同时调用
若 a 的类型是个结构体  可能会出现 a 没完全初始化 
就被另一个线程返回了
不过只初始化一次是有保证的

#23


就是初始化顺序的顺序问题。

我想解决的,正是:

假如全局变量A的初始化,依赖于全局变量B的初始值。

我有什么方法,可以确保全局变量B,必先会被初始化?

既然是全局,那么你的定义就放一起定义,要用到的地方extern 就好了。

能不用全部变量尽量不要用。

#24


我的题目正好就是问这个问题啊。


引用 23 楼 ganpengjin1 的回复:
就是初始化顺序的顺序问题。

我想解决的,正是:

假如全局变量A的初始化,依赖于全局变量B的初始值。

我有什么方法,可以确保全局变量B,必先会被初始化?

既然是全局,那么你的定义就放一起定义,要用到的地方extern 就好了。

能不用全部变量尽量不要用。


引用 19 楼 ganpengjin1 的回复:
给你说下吧:
int a1 = 1191;
 
extern int b2;
int b3 = b2 + 1;

好比这个,你确定是b2完之后再出初始化b3么,没人能够保证。

#25


对于C语言和C++语言来说,没有任何办法能解决楼主关于全局变量初始化依赖的问题。

是没有任何办法,而不是假设什么就能解决。

#26


引用 22 楼 u013486147 的回复:
你谈到了多线程问题,我刚好就是为了解决多线程的一些问题,而需要初始化一些全局变量。


Quote: 引用 20 楼 wangjunsheng 的回复:

可以用函数的静态变量来 处理初始化顺序

int get_a()
{
static int a = 3;
return a;
}

但是在多线程下得小心
get_a() 在2个线程下同时调用
若 a 的类型是个结构体  可能会出现 a 没完全初始化 
就被另一个线程返回了
不过只初始化一次是有保证的


多线程的话
在别的线程启动前  由主线程  主动调用初始化  如
void init()
{
    int n = get_a(); // init get_a() 中的 static int a;
    ...
}

函数的静态变量可以解决变量初始化顺序的问题
试试吧

#27


把所有全局变量都改成函数吧.

//int g = 3;
//declaration
int* g();
//implementation
int* g()
{
  static int g = 3;
  return &g;
}

#28


引用 楼主 u013486147 的回复:
例子:
********************file1.cpp

int a1 = 1191;

extern int b2;
int b3 = b2 + 1;


********************file2.cpp

extern int a1;
int a2 = a1 + 1;

extern int b1;
int b2 = b1 + 1;


********************file3.cpp

extern int a2;
int a3 = a2 + 1;

int b1 = 2212;



********************main.cpp

extern int a3;
extern int b3;
int main()
{
std::cout<<a3<<std::endl;
std::cout<<b3<<std::endl;
}






猜猜上面的a3和b3的输出结果,是否正确?结果是有问题的。


C++只保证了同一个文件里的全局变量是按顺序初始化的,不同文件的不保证顺序

#29


但是的确还有一个多线程的问题:

static int g = 3;

这两行代码,有可能两个线程同时执行。





引用 27 楼 mujiok2003 的回复:
把所有全局变量都改成函数吧.


//int g = 3;
//declaration
int* g();
//implementation
int* g()
{
  static int g = 3;
  return &g;
}

#30


全局对象也有多线程竞争访问问题. 
引用 29 楼 u013486147 的回复:
但是的确还有一个多线程的问题:

static int g = 3;

这两行代码,有可能两个线程同时执行。







Quote: 引用 27 楼 mujiok2003 的回复:

把所有全局变量都改成函数吧.


//int g = 3;
//declaration
int* g();
//implementation
int* g()
{
  static int g = 3;
  return &g;
}

#31


《程序员的自我修养——链接、装载与库》
《Windows PE权威指南》

#32


多线程的话,就加锁吧。

#33


不要写依赖于编译顺序的程序。
不过,貌似用pragma编译指令可以有办法规定变量的初始化顺序。

#34


在C里面这代码是Error 多干脆

#35


从编程规范角度, 这些全局变量既然相互关联, 就应该集中在一个源文件中定义, 其他文件用extern引用.

#36


依赖于编译器,初始化顺序只保证同一文件,不同文件,编译器执行不确定。

#37


C++难道没有规定,全局变量的初始化顺序?没有自动调整的机制?编译器有BUG?

#38


引用 17 楼 u013486147 的回复:
我刚才封装了函数来初始化,还是有问题啊,结果还是不正确。

我现在的问题是:全局变量的初始化,需要依赖其他全局变量。

这里可能存在一些全局变量初始化的先后顺序问题,觉得比较难搞。



Quote: 引用 16 楼 luciferisnotsatan 的回复:

Quote: 引用 12 楼 u013486147 的回复:

那全局变量的使用,应该遵循什么原则?
或是没有原则?你有没有好的经验传授一下?

Quote: 引用 8 楼 luciferisnotsatan 的回复:

Quote: 引用 6 楼 u013486147 的回复:

导致不正确性的根源是?

Quote: 引用 5 楼 derekrose 的回复:

Quote: 引用 4 楼 u013486147 的回复:

这种代码有什么问题?违反了C++的什么规定?还是什么原则?

Quote: 引用 3 楼 luciferisnotsatan 的回复:

谁让你写这种代码的。立刻收拾东西,然后找人事把工资结一下。


会导致不确定的行为 

C++对这些不做规定,是为了让编译器能够更好的优化代码。

经验就是,别在全局里写这种代码。
extern int a1;
int a2 = a1 + 1;
 
extern int b1;
int b2 = b1 + 1;

如过非要给全局做初始化,那就做个init函数,来赋值

方法也不难:写一个类,把全局变量的初始化逻辑写在类的构造函数里,然后建立一个该类的全局变量。

#39


楼主如果用VC编译器的话,就用#pragma init_seg(lib)吧

看看这个:
HOW TO: Use #pragma init_seg to Control Static Construction

#40



//dec.h
#ifndef __DEC_H__
#define __DEC_H__
extern a1,a2,a3,b1,b2,b3;
#endif

//dec.cpp
#include "dec.h"
int a1 = 1191;
int a2 = a1 + 1;
int a3 = a2 + 1;
int b1 = 2212;
int b2 = b1 + 1;
int b3 = b2 + 1;

//main.cpp
#include <iostream>
#include "dec.h"
int main()
{
   std::cout<<a3<<std::endl;
   std::cout<<b3<<std::endl;
}

LZ 这样试试吧,既然全局变量有依赖关系,你何必分开来定义,放在一个编译单元里定义不就行了~

#41


引用 40 楼 vipcxj 的回复:

//dec.h
#ifndef __DEC_H__
#define __DEC_H__
extern a1,a2,a3,b1,b2,b3;
#endif

//dec.cpp
#include "dec.h"
int a1 = 1191;
int a2 = a1 + 1;
int a3 = a2 + 1;
int b1 = 2212;
int b2 = b1 + 1;
int b3 = b2 + 1;

//main.cpp
#include <iostream>
#include "dec.h"
int main()
{
   std::cout<<a3<<std::endl;
   std::cout<<b3<<std::endl;
}

LZ 这样试试吧,既然全局变量有依赖关系,你何必分开来定义,放在一个编译单元里定义不就行了~


extern int a1,a2,a3,b1,b2,b3;

笔误,少了个int。

#42


c++定义变量一定要赋初值,不然在运行时时随机赋值的。

#43


晕啊,你仔细想想,如果有顺序的话,这么多的文件,应当按照一个什么样的顺序呢???? C++难道没有规定,全局变量的初始化顺序?没有自动调整的机制?编译器有BUG?