www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - std.stream.BufferedStream has upsizing bug

I want to modify a file "test.img".
The file size is 1.4MB.
But this code expands the file to 4GB.
(dmd 0.144 for Windows)

import std.stream;

int main(char[][] args)
    Stream fd_img = new BufferedFile("test.img",
        FileMode.In | FileMode.Out);
    ubyte buf[1];
    buf[0] = 0x01;
    uint write_size = fd_img.writeBlock(&buf[0], 1);
    return 0;

Because std.stream.BufferedStream has "uint bufferSourcePos"
and std.stream.Stream has
"abstract ulong seek(long offset, SeekPos whence)".

The problem occurs on follow line.

streamPos = s.seek(-bufferSourcePos, SeekPos.Current);

D doesn't extend sign on this case.
D treats this as follow.
 -uint -> uint -> long

This is the sample code.
import std.stdio;

void func(long lx)
    writefln("%d", lx);

int main(char[][] args)
    uint x = 1;
    return 0;


So, this is the right code.
streamPos = s.seek(-cast(long)(bufferSourcePos), SeekPos.Current);

dmd Linux version doesn't have this problem.
Because lseek() recasts (wrong) long to int.
(This means max file size on Linux is 4GB. :( )

This problem has also D's error reporting
 and/or type casting problem.

If D casts -uint to long directly, the problem doesn't occur.
But it requires "result type" at determining function.
Bottom up approach dislike it.

If direct cast is difficult, I want the warning report.
D doesn't warn this now.
I think "-uint -> uint" is right. It's sometime useful.
(Is "-uint -> int or long" better?)
(Is reporting error for "-uint" better?)
"uint -> long" is right.
But I think D should report "warning" on this combined case if D can catch.
(If two operations are separated too far, it is difficult to find probably.)

Thank you for reading my poor english.
Jan 26 2006