65,187
社区成员




#include <iostream>
using namespace std;
class A
{
public:
//A(){}
int * pI;
int i;
};
int main()
{
A a;
//A& b = a;
cout<<a.pI<<endl;
system("pause");
}
#include <iostream>
using namespace std;
struct A
{
int * pI;
int i;
};
int main()
{
A a;
A* b = &a;
cout<<a.pI<<endl;
system("pause");
}
#include <iostream>
using namespace std;
struct A
{
int * pI;
int i;
};
void f (A&) {}
int main()
{
A a;
f(a);
cout<<a.pI<<endl;
system("pause");
}
#include <iostream>
using namespace std;
struct A
{
int * pI;
int i;
};
void f (A*) {}
int main()
{
A a;
//f(&a);
cout<<a.pI<<endl;
system("pause");
}
总结一下,我觉得 vs2010 的逻辑是这样的。
(1) debug 模式下 /RTC 开关打开后,会执行必要的运行时检查,比如为初始化变量的使用。
(2) 具体的实现逻辑是,分配其他变量,用以记录被检测变量是否初始化,如果没有则调用 __RTC_UninitUse 中断程序。
(3) 但是判断某变量初始化是各很复杂的问题。如果只有一个变量 a 的时候,那么对于 a.pI 的初始化只能通过 a 完成,所以只需要检测对 a 的动作即可。但是当引入 a 的引用或指针时,同样的初始化可以通过这些间接的途径完成,因此检查工作就变得复杂了,而且随着这类间接途径的增加,检查的复杂度之迅速变得不可控制的。尤其是怎样检查和到底支持到什么样的复杂度很不容易通过程序量化,基本像个人工智能的复杂过程。所以我猜,vs2010 如果发现存在间接路径(引用或指针)能够影响变量的初始化,则取消对应的检查,因为反正也不可能检测所有路径,索性就干脆别检查了。结果就是加了个引用,貌似 a.pI 就初始化了似的。其实不然,只是 vs2010 太累了,不帮你进行运行时检查了。