This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]