We recently switched from using libstc++ to libc++ in our code base, so that we could move up to using C++11, and found to our horror that istream::seekg seems to be broken for custom streams. We use a lot of different custom stream objects, so this is rather worrying.
It looks like this is not a problem with libc++'s implementation of the standard, per se, but some sort of a ABI difference between the compiled library that ships with Xcode 6.3 and clang's output that links with it.
Here's a sample piece of code:
#include <iostream>
#include <cassert>
class custombuf : public std::streambuf
{
public:
virtual pos_type seekoff(
off_type offset,
std::ios_base::seekdir dir,
std::ios_base::openmode mode = std::ios_base::out |
std::ios_base::in)
{
return pos_type(off_type(-1));
}
};
class customstream : public std::istream
{
public:
customstream() : std::istream(&m_buf) {}
private:
custombuf m_buf;
};
int main()
{
customstream c;
c.clear();
c.seekg(-5, std::ios_base::beg);
// seekoff() in our custom buffer always returns -1, which should cause seekg() to
// mark the call as failed.
assert(c.fail());
return 0;
}This is then compiled with:
> clang++ -o custombuf custombuf.cppUnder normal circumstances, the assert on line 38 should not fire, since seekoff() is indicating that we cannot seek, and so seekg() should have set the fail bit. However the comparison between the return value of seekoff() and pos_type(-1) in seekg fails and so that doesn't happen.
I've logged a bug with Apple a week back, but haven't seen a response yet. I was wondering if someone else had run into this and had any suggestions (aside from re-compiling libc++ and shipping our own version, which would be rather sub-optimal).