This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
RE: [Patch] Fix libstdc++/11378 (take2) + xsputn optmizations
- From: Pétur Runólfsson <peturr02 at ru dot is>
- To: "Nathan Myers" <ncm-nospam at cantrip dot org>,<libstdc++ at gcc dot gnu dot org>
- Date: Thu, 10 Jul 2003 20:35:43 -0000
- Subject: RE: [Patch] Fix libstdc++/11378 (take2) + xsputn optmizations
Nathan Myers wrote:
>> #include <ios>
>> int main()
>> {
>> std::streamoff m, n;
>> std::streamoff o(m - n);
>> }
>
> Uh-oh. If it's a conforming program,
I don't think there can be any doubt about that. The descriptions
of both stringbuf::seekoff and strstreambuf::seekoff use arithmetic
involving streamoff values without explicit conversions to
streamsize.
> then adding overloads that make
> it _not_ truncate its result is not allowed. That looks like a defect.
I agree.
Elsewhere, Nathan wrote:
> The type
> safety argument dictates that we should use a class type for
> std::streamoff containing a 64-bit integer type,
That seems absolutely neccessary so that errors such as
fstream f;
...
long pos = f.tellg();
can be caught at compile time, especially since this works as
expected with the current implementation.
> and publicly defining
> (only!) the operations required in 27.4.3.2,
Unless I'm missing something, I don't see any requirement that
streamoff or fpos<> be DefaultConstructible.
> 27.4.3.2
> requires that it convert explicitly (but not implicitly!) from,
> [...] std::streamsize
The descriptions of basic_istream::tellg and basic_ostream::tellp
seem to assume an implicit conversion from streamsize to streamoff.
I don't see any reason to make that conversion explicit, since it
is required to be lossless.
However, I don't see any requirement that the conversion from
fpos<> to streamoff be implicit. Since that is a lossy conversion
(it loses the conversion state) fpos<>::operator streamoff()
should be dropped and streamoff should have an explicit
constructor taking a fpos<>.
> and implicitly to, std::streamsize
If streamoff is 64-bits and streamsize 32, then the conversion
from streamoff to streamsize is lossy. It would be nice if the
compiler could give a warning about that.
streamoff o;
...
streamsize s = o; // Should get a warning pointing to this line!
One way to achieve this (not neccesarily the only, or the best way)
is to define streamoff::operator long long(), and not
streamoff::operator streamsize().
---
All this looks so complex that I wonder if the best way to solve
it is to just add header <ext/fstream64> that contains:
typedef ... streamoff64; // Meets the requirements on streamoff,
// plus has implicit, lossless conversions to and from 64-bit
// integers.
template <typename S> class fpos64; // Same as fpos, but has
// conversions to and from streamoff64.
typedef fpos64<mbstate_t> streampos64;
template <typename C>
class char_traits64
{
typedef streamoff64 off_type;
typedef streampos64 pos_type;
// otherwise the same as char_traits<C>
};
typedef basic_filebuf<char, char_traits64> filebuf64;
// Same for wfilebuf64, ifstream64, ofstream64, fstream64.
This isn't so very far fetched; after all, it is what the C
library does (off_t vs. off64_t, fseeko vs. fseeko64 etc.).
It can even be done without breaking ABI compatibility, it
only requires adding an overload of __basic_file::seekoff
that takes a streamoff64 and calls lseek64.
Regards,
Petur