我们的VB6应用存在一个非常奇怪的控制流问题。似乎双精度值的不平等比较不正确。此外,添加 MsgBox
通话似乎有一些副作用。最后,在IDE中运行与编译之间,与使用哪台计算机运行编译器之间,存在差异。
我们无法在应用本身之外重现此内容,但是下面是旨在传达基本信息的代码段。
在第一个代码示例中,d(i)
的所有值均为>>> 1
(大约2500万)。因此,应始终采用If..Then
的第二个分支。在IDE中,这是发生的。在从一台PC编译的EXE中,第二个分支仅用于i=1
-不正确。
代码块1:
Dim d(1 to 4) as Double
Dim result(1 to 4) as Double
' ... Some logic to set the value of d goes here
For i = 1 To 4
If d(i) < 1 Then
result(i) = 0
Else
result(i) = numerator(i) / d(i)
End if
Next
现在,如果将代码修改为包括MsgBox
个调用,则一切正常。第二个分支一直都在占用(!!)
MsgBox
调用似乎有一些副作用,可以消除上面提到的问题。
代码块2:
If d(i) < 1 Then
result(i) = 0
MsgBox "Took first branch, d(i) = " & CStr(d(i))
Else
result(i) = numerator(i) / d(i)
MsgBox "Took second branch, d(i) = " & CStr(d(i))
MsgBox "Some other info"
End if
需要精确的MsgBox
调用集。如果消除了任何一个,或者将两者合并,则不会发生“副作用”,并且i> 1的不等式将被错误地评估。
更多详细信息:
将VB6设置为在编译(针对本机代码)时使用“无优化”将解决控制流问题。
在另一台PC上进行编译会产生一个EXE,但没有出现此问题。生成的EXE是二进制不同的(甚至考虑到版本号等)
在IDE中运行/逐步跟踪永远不会重现该问题
这真是太奇怪了,我们开始认为“编译器坏了”。
VB6运行时或编译器中是否有一个晦涩的问题导致……内存损坏?堆栈损坏?还是一些未知的旧缓存数据污染了EXE? PC上的不良硬件会编译错误?这些都是极不可能的,但我不确定还有什么想法。
欢迎任何提示。
更新:我们正在考虑的是编译运行不正常的EXE的计算机上可能没有VB6 SP6。如果我们确认相关,我将再次更新。