Broken streampos::operator+() when reaching 2GB ?
#include <fstream>
#include <iostream>
#include <ostream>
#include <memory.h>
using namespace std;
/* compile :
cl /EHcs big.cc
*/
/* This program advances the file position after 2GB,
by adding offset to the file-position variable.
This operation is broken in VC++ 2003 and 2005. Same for NTFS and
FAT32.
Any idea how to fix this ?
*/
/* Just for printing */
class ust {
public:
int i[6];
} ;
/* Just print */
void showpos(streampos & k) {
ust u;
std::cout <<"POS=";
memcpy((char*)(&u),(char*)(&k),sizeof(k));
for (int j=0;j<6;j++) {
std::cout << " " << u.i[j] ;
};
std::cout << endl;
}
int main()
{
ofstream oPlot ("big.txt", ios::binary | ios::out);
static char big[10000000];
for (int i=0;i<10000000;i++) big[i]='e';
for (int i=1;i<=25;i++) {
oPlot.write((char*) big,10000000);
oPlot.flush();
/* Wrote a chunk */
streampos p=oPlot.tellp();
std::cout << "Wrote ";
std::cout << (long long int) p << " good= "<< oPlot.good()
<<" sizeof(p)=" << sizeof(p) << endl;
showpos(p);
streamoff f 0000000;
/* Moves 200MB forward */
p=p+f;
oPlot.seekp(p);
std::cout << "Seeks ";
showpos(p);
/* Asks where we are now ? */
p=oPlot.tellp();
std::cout << "Tells ";
showpos(p);
/* oPlot becomes bad after we reach 2GB */
std::cout << "Details " <<(long long int) p << " good= "<<
oPlot.good() << " sizeof(f)=" << sizeof(f) << endl;
std::cout << endl;
}
return 0;
}
/*
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
D:\e\run\B684>big
Wrote 10000000 good= 1 sizeof(p)=24
POS= 0 0 10000000 0 0 0
Seeks POS= 200000000 0 10000000 0 0 0
Tells POS= 0 1244832 210000000 0 0 14352240
Details 210000000 good= 1 sizeof(f)=4
Wrote 220000000 good= 1 sizeof(p)=24
POS= 0 1244832 220000000 0 0 14352240
Seeks POS= 200000000 1244832 220000000 0 0 14352240
Tells POS= 0 1244832 420000000 0 0 14352240
Details 420000000 good= 1 sizeof(f)=4
Wrote 430000000 good= 1 sizeof(p)=24
POS= 0 1244832 430000000 0 0 14352240
Seeks POS= 200000000 1244832 430000000 0 0 14352240
Tells POS= 0 1244832 630000000 0 0 14352240
Details 630000000 good= 1 sizeof(f)=4
Wrote 640000000 good= 1 sizeof(p)=24
POS= 0 1244832 640000000 0 0 14352240
Seeks POS= 200000000 1244832 640000000 0 0 14352240
Tells POS= 0 1244832 840000000 0 0 14352240
Details 840000000 good= 1 sizeof(f)=4
Wrote 850000000 good= 1 sizeof(p)=24
POS= 0 1244832 850000000 0 0 14352240
Seeks POS= 200000000 1244832 850000000 0 0 14352240
Tells POS= 0 1244832 1050000000 0 0 14352240
Details 1050000000 good= 1 sizeof(f)=4
Wrote 1060000000 good= 1 sizeof(p)=24
POS= 0 1244832 1060000000 0 0 14352240
Seeks POS= 200000000 1244832 1060000000 0 0 14352240
Tells POS= 0 1244832 1260000000 0 0 14352240
Details 1260000000 good= 1 sizeof(f)=4
Wrote 1270000000 good= 1 sizeof(p)=24
POS= 0 1244832 1270000000 0 0 14352240
Seeks POS= 200000000 1244832 1270000000 0 0 14352240
Tells POS= 0 1244832 1470000000 0 0 14352240
Details 1470000000 good= 1 sizeof(f)=4
Wrote 1480000000 good= 1 sizeof(p)=24
POS= 0 1244832 1480000000 0 0 14352240
Seeks POS= 200000000 1244832 1480000000 0 0 14352240
Tells POS= 0 1244832 1680000000 0 0 14352240
Details 1680000000 good= 1 sizeof(f)=4
Wrote 1690000000 good= 1 sizeof(p)=24
POS= 0 1244832 1690000000 0 0 14352240
Seeks POS= 200000000 1244832 1690000000 0 0 14352240
Tells POS= 0 1244832 1890000000 0 0 14352240
Details 1890000000 good= 1 sizeof(f)=4
Wrote 1900000000 good= 1 sizeof(p)=24
POS= 0 1244832 1900000000 0 0 14352240
Seeks POS= 200000000 1244832 1900000000 0 0 14352240
Tells POS= 0 1244832 2100000000 0 0 14352240
Details 2100000000 good= 1 sizeof(f)=4
Wrote 2110000000 good= 1 sizeof(p)=24
POS= 0 1244832 2110000000 0 0 14352240
Seeks POS= 200000000 1244832 2110000000 0 0 14352240
Tells POS= -1 1244832 0 0 0 14352240
Details -1 good= 0 sizeof(f)=4 <===========
BAD BAD BAD
Wrote -1 good= 0 sizeof(p)=24
POS= -1 1244832 0 0 0 14352240
Seeks POS= 199999999 1244832 0 0 0 14352240
Tells POS= -1 1244832 0 0 0 14352240
*/