网上一篇文字
微软的一个最令我佩服的一个BUG,CFile类的GetLength函数
以下代码在VC6下编译,通过。代码的目标是读取一个文本文件中的所有非空行,并且打印出来
但是会存在问题。如果daroot.txt比较大,有上千行,那么,将有可能最后循环读取其中的几行。并且永远也不能结束。
CStdioFile file("daroot.txt",CStdioFile::modeRead);
while(file.GetPosition()<file.GetLength())
...{
CString strTmp;
file.ReadString(strTmp);
if(strTmp.GetLength()>0)
puts(strTmp);
}
导致该问题的是file.GetLength()的调用,GetLength()属于CFile类,但是其中做了Seek的操作,导致,文件的当前位置重置到原来的某个地方。所以file永远也不能读取完毕。
为什么会这样呢?
CFile中的GetLength的代码是这样的
DWORD CFile::GetLength() const
...{
ASSERT_VALID(this);
DWORD dwLen, dwCur;
// Seek is a non const operation
CFile* pFile = (CFile*)this;
dwCur = pFile->Seek(0L, current);
dwLen = pFile->SeekToEnd();
VERIFY(dwCur == (DWORD)pFile->Seek(dwCur, begin));
return dwLen;
}
说实在的,我不明白一个作为const的GetLength函数,为什么还要调用seek操作,这简直是违规操作!
但是更绝的是,本来编译程序不允许这样的违规操作的,于是CFile::GetLength() 的代码编写者使用了一个"技巧"
CFile* pFile = (CFile*)this; 强制转换!!!!
我简直无语,人不能无耻到这种地步!
教训:永远也不要调用GetLength()函数,除非你才刚刚打开这个file