灵感的来临,没有任何预兆;灵感的消失,也不会有告别仪式;用文字记下她们吧,让灵感永存……

Visual C++ 6 的 BUG:

davies 发表于 2006 年 08 月 13 日

意外的发现一个Visual C++ 6 的bug :

调试C++代码时,用 Watch 察看一个表达式的值,如果该表达式中同时有 __int64 和 double 两种数值类型,其结果就会错得离谱,比如 __int64(0)+1.0,用 watch 查看的值竟然为 460718241880017408 !

这个古怪结果的十六进制表示为 0x3ff0000000000000。根据某某标准,双精度浮点数1.0用8个字节来表示,上面那个古怪结果正是1.0。可以通过如下方法查看1.0的表示方法:

double a = 1.0;
__int64 *a64 = (___int64*)a;

用 watch 查看 *a64 的值,并用十六进制表示,就可以看到是0x3ff0000000000000。

原来是用 watch 查看表达式时对 double 和 __int64 之间的类型转换有问题,由于它们是具有相同精度的,都是8个字节,不知道是从__int64转到double,还是从double转到__int64,居然就不做类型转换了,直接把double类型当作__int64类型来处理,所以出错。

我们来继续发掘,查看表达式 1.0+__int64(10)的值,居然是 1.0 ! 结合上面的例子可以看出,它是把后面一种数据类型直接当作前一种数据的类型来处理,而不做任何转换。10的十六进制表示为 0x000000000000000a,当作double类型的话,就是0了。

不过不用担心,这个bug并不影响程序的运行,代码执行结果还是正确的。

再来看看 Visual C++ 2005 的表现,不管是1.0+__int64(1) 还是 __int64(1)+1.0,其结果都是2.0,类型为double,终于做了正确的处理。Visual C++ 2003中没有试过,不知道有没有该问题。

网友留言:

Re: Visual C++ 6 的 BUG:1. 发表于 2006 年 08 月 15 日 4:53 p.m.

还有这种问题,KK。

Re: Visual C++ 6 的 BUG:2. 发表于 2006 年 08 月 16 日 12:13 a.m.

不是不知道,一试下一跳

Re: Visual C++ 6 的 BUG:3. 发表于 2006 年 11 月 16 日 9:47 a.m.

我试了,不是这样。

我打了sp6补丁!

Re: Visual C++ 6 的 BUG:4. 发表于 2006 年 11 月 16 日 9:56 a.m.

可能在sp6中已经将这个Bug修正,不错

我来留言