发现Delphi的一个小bug, 看看!

flyinwuhan 2003-10-22 07:04:53
var
i, j : DWORD;
begin
j := 0;
for i:=0 to j-1 do
begin
哈哈,成了一个死循环,大家以后小心啊!
end;
end;
...全文
19 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
ly_liuyang 2003-10-23
  • 打赏
  • 举报
回复
DWORD类型
是pazee(耙子)说的正确
耙子 2003-10-23
  • 打赏
  • 举报
回复
楼主再钻牛角尖,和他解释过多意义不大了。
rick29 2003-10-23
  • 打赏
  • 举报
回复
知道这样的情况,就用downto,实在不行了就不要用for循环。既然是写程序的,这点就不能懒IDE。
qiume 2003-10-23
  • 打赏
  • 举报
回复
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
function GetDWORD(const A: DWORD): DWORD;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.GetDWORD(const A: DWORD): DWORD;
asm
MOV EAX, A // 调式时,看看 A 的值就知道了!
end;

procedure TForm1.Button1Click(Sender: TObject);
var
j: DWORD;
begin
j := 0;
ShowMessage(IntToStr(GetDWORD(J - 1)));
end;

end.
flyinwuhan 2003-10-23
  • 打赏
  • 举报
回复
告楼上各位:
var
i,j:DWord;
请把DWord换成Integer再看看会有什么情况?

也许delphi并没有错,可是如果是C ,for (i=0;i<(j-1);i++ )会有这种情况吗!!!

我只知道在这种情况下,我不需要计算机把j-1换成4294967295。

在运行期间,你无法保证(j-1)不是负数,可一旦它是负数,你就不可能得到你想要得结果。

所以提醒大家,用for循环的时候一定要检查一下循环变量是否正确(如果你用Delphi)

欢迎继续讨论!
zhoutian618 2003-10-23
  • 打赏
  • 举报
回复
DWORD是无符号型数!!
szkingrose 2003-10-23
  • 打赏
  • 举报
回复
将这小子拖出去痛打50大板,呵呵。
ehom 2003-10-23
  • 打赏
  • 举报
回复
你的翻译就有问题,Pascal就是这么一种语法非常严谨的强类型语言,你可以不用它,但不能说它有错

unsigned int i, j;
j = 0;
for(i=0; i<(unsigned int)(j-1); i++);
//或for(i=0; i<unsigned(j-1); i++);
你应该这样试试

很多时候C中灵活的类型转换可以被滥用并不是好事?
hiflower 2003-10-23
  • 打赏
  • 举报
回复
procedure TForm1.Button1Click(Sender: TObject);
var
i,j:DWord;
begin
j:=0;
ShowMessage(inttostr(j-1)); //看看 j-1 是几吧。4294967295($FFFFFFFF)
exit;

for i:=0 to j-1 do
begin
Caption:=IntToStr(i);
refresh;
end;
flyinwuhan 2003-10-23
  • 打赏
  • 举报
回复
*也许delphi并没有错,可是如果是C ,for (i=0;i<(j-1);i++ )会有这种情况吗!!!

大家见笑了,为什么没有人对上面的话产生质疑呢?

哈哈,其实,在VC中和Delphi是一样的:-)

目前最喜欢的还是Delphi,不过不知道Delphi还能坚持多久......
hiflower 2003-10-23
  • 打赏
  • 举报
回复
Delphi 有严格的类型限制,不像 C 那么自由。
for 循环的初值和终值的数据类型,在比较时都会转换为相应的循环变量的类型。
你的例子中,i 是 DWORD,所以它不可能有负值。
如果 i 是 Integer,j 仍为 DWORD,则会把 j 的值转换为 Integer,同样是 $FFFFFFFF,DWORD 的值是 4294967295,Integer 的值是 -1。

另外,对于 for 语句来说,它的初值和终值是在进入 for 语句时就固定了,不会因为循环中对 j 的改变而影响循环次数。
耙子 2003-10-23
  • 打赏
  • 举报
回复
楼主,
这和Delphi 完全没关系。这能说你是编程序的逻辑存在问题,属于人的问题。

上学的时候有门功课就是计算机算法,讲人的逻辑转换为计算语言的时候需要注意的问题,你这个都是非常简单的例子。

每个语言都有自己的特点特色,不能简单的把两种语言比较。Pascal的 运算优先级还和C有非常大差别呢,你能说pascal的不对。

nyf1220 2003-10-22
  • 打赏
  • 举报
回复
to 把子
呵呵,一语惊醒梦中人呀,
当时没有好好想,
966126 2003-10-22
  • 打赏
  • 举报
回复
我在win2000+delphi6的c400机子下程序死翘了
耙子 2003-10-22
  • 打赏
  • 举报
回复
var
i, j, k : DWORD;
begin
j:= 0;
k:= GetTickCount();
for i:=0 to J-1 do
begin
// 哈哈,成了一个死循环,大家以后小心啊!
end;
ShowMessage(IntToStr(GetTickCount()-k));
end;

我的11466ms 就出来接过了
耙子 2003-10-22
  • 打赏
  • 举报
回复
这个不是BUG。

无符号整数的减法不可能是负数,
也是就说
j :DWORD;
j=0;
j-1 <> -1,而是等于-1的补码,等于 $FFFFFFFF,是最大的32位整数。

我看了Delphi 6汇编出来的代码,证实了这个说法,而且我的电脑(C3 1.0G)也很快循环完了。
耙子 2003-10-22
  • 打赏
  • 举报
回复
j-1 不是-1,而是 $FFFFFFFF-1,是32位中第二大的整数。
lfzyh 2003-10-22
  • 打赏
  • 举报
回复
我还不懂你这样写有什么目的,从0循环到j-1,而j初始值又是0减去1等于: -1 0到-1间如何循环?有几次循环?
flyinwuhan 2003-10-22
  • 打赏
  • 举报
回复
d7 + xp 确实存在此问题
newyj 2003-10-22
  • 打赏
  • 举报
回复
不可能的,这么简单的个问题, d5+sp2,d7,d6+sp2 都没问题
我想没有升级也不应该有错,如果有这种问题delphi也太弱了
加载更多回复(5)

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧