总结一下,我觉得 vs2010 的逻辑是这样的。 (1) debug 模式下 /RTC 开关打开后,会执行必要的运行时检查,比如为初始化变量的使用。 (2) 具体的实现逻辑是,分配其他变量,用以记录被检测变量是否初始化,如果没有则调用 __RTC_UninitUse 中断程序。 (3) 但是判断某变量初始化是各很复杂的问题。如果只有一个变量 a 的时候,那么对于 a.pI 的初始化只能通过 a 完成,所以只需要检测对 a 的动作即可。但是当引入 a 的引用或指针时,同样的初始化可以通过这些间接的途径完成,因此检查工作就变得复杂了,而且随着这类间接途径的增加,检查的复杂度之迅速变得不可控制的。尤其是怎样检查和到底支持到什么样的复杂度很不容易通过程序量化,基本像个人工智能的复杂过程。所以我猜,vs2010 如果发现存在间接路径(引用或指针)能够影响变量的初始化,则取消对应的检查,因为反正也不可能检测所有路径,索性就干脆别检查了。结果就是加了个引用,貌似 a.pI 就初始化了似的。其实不然,只是 vs2010 太累了,不帮你进行运行时检查了。 [解决办法]
(1) #11 只是我基于一些现象的猜测,看起来有道理,实际上也可能是错误的。 (2) VS 有理由对未初始化的指针变量做检查,即便程序并没有对该指针解引用。in particular, c++11 4.1/1 says: A glvalue (3.10) of a non-function, non-array type T can be converted to a prvalue. ... if the object is uninitialized, a program that necessitates this conversion has undefined behavior. 避免 UB 是好程序的基本目标之一,VS 作为编译器采取措施帮助程序员无可厚非。 [解决办法] vs2012是没有问题的,只是pi指针没有初始化的问题,所以输出为0000000,其实个人觉得你这么做没有意义,你得出的结果可能会随着编译器的不同出先不同结果,毕竟指针属于悬浮指针,它的值是不确定的 [解决办法] 个人认为,引用后初始化,显然不如定义初始化(包含构造函数初始化)好。