|
|
发表于 2007-4-28 10:34:00
|
显示全部楼层
Re:C++问题,谁能告诉我哪里出了错啊!
我分别在 vs2003 和 vs2005sp1 中测试了一下,发现在 2005 中只调用了一次,2003 中确实调用了2次,楼上几位说是由于内联展开的问题造成的,我觉得实际情况还不一定是这样,通过观察 Release 版的汇编代码可以看到,在 2003 中:
static Clock* GetClock()
{
static Clock c;
00401000 mov cl,byte ptr [`Clock::GetClock'::`2': S1 (4086C4h)]
....
return &c;
}
int Update()
{
std::string name;
for(int i=0; i<4; ++i)
{
Clock::GetClock();
00401066 test byte ptr [`Clock::GetClock'::`2'::$S3 (4086C8h)],bl
...
}
return 0;
}
可以看到 2 处地址并不相同,这是造成调用两次构造函数的主要原因。而在 2005 中:
int main()
{
Clock::GetClock();
00401000 mov eax,1
00401005 test byte ptr [`Clock::GetClock'::`2'::`local static guard' (403020h)],al
....
Update();
return 0;
}
int Update()
{
std::string name;
for(int i=0; i<4; ++i)
{
Clock::GetClock();
00401070 test byte ptr [`Clock::GetClock'::`2'::`local static guard' (403020h)],bl
...
}
return 0;
}
两处地址完全相同,所以只调用一次构造函数。按照语法来讲,应该调用一次,只要是 static 变量,应该是保存在程序的静态数据空间中,静态数据空间中存储的变量在程序 c++ runtime 调用 main 函数之前就会初始化,而不是等调用到这个函数时才会初始化。所以通过 2003 和 2005 中的不同表现来看,我认为是 2003 编译器的一个缺陷,有可能是个 bug,在 2005 中被修正了。如果把类定义改成如下:
class Clock
{
private:
Clock();
~Clock();
static Clock c;
public:
static Clock* GetClock()
{
return &c;
}
};
在 cpp 中声明:
Clock Clock::c;
则在 2003 中是调用了一次,所以由此可见 2003 中对于内联函数内的静态变量的优化是有问题的。
|
|