论坛首页 综合技术论坛

《Essential c++中文版》读书笔记--静态局部变量(一)

浏览 17557 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-01-19  
在目前大部分常用的操作系统中,可执行文件里都是按照特定文件格式放置所需要的代码和数据,例如windows的PE(COFF), linux的ELF等,所以像有初值的全局变量一般都会放在一个固定的data section, COFF里面是.data(.bss是不需要初始化的全局变量),很多操作系统的loader会支持将这些数据段在进入main之前就放置到内存中去,但这不是唯一方法.还有的方法就是有和操作系统相关的library提供代码在main前加载,有些干脆由编译器自己产生加载的代码.
所以说具体如何实现要大家商量好,当然一般情况下是OS已经决定了,编译器只能被动的去匹配而已.
C++的构造函数是在对象被实例化的时候调用的,这个和全局变量的初始化有异曲同工的作用.
对于局部静态变量的初始化则完全是在函数入口处添加代码来做到的,这一点也就是前面提到的为了保证初始化的次序.但是这种动作不会因为有这种特性而消除初始化错误的可能,因为代码逻辑一旦错误,依然得不到正确的初始化值,所以不推荐这种方法,与其惴惴不安的使用不如老老实实传参数不是更好?
不过这种做法有个好处...对于搞破解来说多了一道坎~~
0 请登录后投票
   发表时间:2007-01-19  
七猫 写道

如上面的这个例子,
其中i是放在数据段,已经被初始化好了,就是1,
CA,CB的构造函数是放在好像是一个表里面的,由MainCrtStartup来执行(用_init_term来完成的),有兴趣的可以直接看C库代码。我不贴了。


构造函数和全局变量不一样喔~
你所指的构造函数在一个表里,实际上是C++的特性,不过总的来说方法就那么几种,无论变量还是函数~
0 请登录后投票
   发表时间:2007-01-19  
很奇怪为什么会扯成这个样子 ……

问题的关键在于全局变量的构造次序。如果你的全局变量不是 int 而是一个类类型的话,那么它需要先构造才能正常使用,而问题就在于构造函数的调用次序是 C++ 标准没法保证而由实现定义的。比方说:

a.cpp
const string msg = "Hello, world!";

b.cpp
const string display = msg;

这里 msg 和 display 分别是位于 a.cpp 和 b.cpp 的两个全局变量。如果 display 的构造函数先于 msg 的构造函数被调用,就会出现奇怪的结果,比如说 display 变成一个空字符串什么的。这里的问题就是这个次序是 C++ 标准所不保证的,而是由编译器的实现来决定。因此如果你的代码依赖于全局变量的构造次序,你的代码就有可移植性问题。
0 请登录后投票
   发表时间:2007-01-19  
Elminster 写道
很奇怪为什么会扯成这个样子 ……

问题的关键在于全局变量的构造次序。如果你的全局变量不是 int 而是一个类类型的话,那么它需要先构造才能正常使用,而问题就在于构造函数的调用次序是 C++ 标准没法保证而由实现定义的。比方说:

a.cpp
const string msg = "Hello, world!";

b.cpp
const string display = msg;

这里 msg 和 display 分别是位于 a.cpp 和 b.cpp 的两个全局变量。如果 display 的构造函数先于 msg 的构造函数被调用,就会出现奇怪的结果,比如说 display 变成一个空字符串什么的。这里的问题就是这个次序是 C++ 标准所不保证的,而是由编译器的实现来决定。因此如果你的代码依赖于全局变量的构造次序,你的代码就有可移植性问题。


说的是没有错,这就要考验编译器的能力,如果编译器分析够全面这种相关性是可以处理的,并且可以保证其正确性,但正如你所说如果编译器作的不好那么移植性将大打折扣.
我个人来说是不会使用这种代码的,宁可自己在用到的地方赋值好了,多写一点代码,保证不会出错
0 请登录后投票
   发表时间:2007-01-19  
另外这种语法在C中是不允许的.
C++允许,而且只要是符合C++标准的编译器都会合理的处理先后顺序的,除非写出
a.cpp
int gi = gj+3;

b.cpp
int gj = gi+13;
这样bt的代码,如果这样很多编译器也不报错,但是结果就不可预期了,谁让你自己写出这样矛盾的代码呢?

0 请登录后投票
   发表时间:2007-02-20  
Elminster 写道
很奇怪为什么会扯成这个样子 ……

问题的关键在于全局变量的构造次序。如果你的全局变量不是 int 而是一个类类型的话,那么它需要先构造才能正常使用,而问题就在于构造函数的调用次序是 C++ 标准没法保证而由实现定义的。比方说:

a.cpp
const string msg = "Hello, world!";

b.cpp
const string display = msg;

这里 msg 和 display 分别是位于 a.cpp 和 b.cpp 的两个全局变量。如果 display 的构造函数先于 msg 的构造函数被调用,就会出现奇怪的结果,比如说 display 变成一个空字符串什么的。这里的问题就是这个次序是 C++ 标准所不保证的,而是由编译器的实现来决定。因此如果你的代码依赖于全局变量的构造次序,你的代码就有可移植性问题。
强烈同意楼上的。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics