Opened 12 years ago

Closed 7 years ago

#5139 closed Bugs (fixed)

Initial Stream Position in Boost.Interprocess.Vectorstream

Reported by: charles@… Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: interprocess
Version: Boost 1.57.0 Severity: Problem
Keywords: Cc: superpacko@…

Description

When the boost::interprocess::basic_vectorstream<T> is default-constructed, tellp() initially returns an invalid stream position. Presumably, it should return position 0 before anything is inserted into the stream, but instead it returns -1.

This is easy to reproduce:

Code highlighting:

#include <sstream>
#include <boost/interprocess/streams/vectorstream.hpp>

int main()
{
        std::stringstream ss;
        std::cout << ss.tellp() << " ";

        boost::interprocess::basic_vectorstream<std::vector<char> > vs;
        std::cout << vs.tellp() << std::endl;
}

This should output: 0 -1

In contrast with std::stringstream, we see that boost::interprocess::basic_vectorstream begins with an invalid stream position. It should begin at 0, but it begins at -1.

Change History (5)

comment:1 by anonymous, 12 years ago

I think the problem is with boost::interprocess::basic_vectorstream::seekoff.

On line 284 of boost/interprocess/streams/vectorstream.hpp it reads:

Code highlighting:

    //Test for logic errors
    if(!in & !out)
       return pos_type(off_type(-1));
    else if((in && out) && (dir == std::ios_base::cur))
       return pos_type(off_type(-1));
    else if((in  && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) ||
             (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0)))
       return pos_type(off_type(-1));

This code doesn't account for the possibility that the internal vector is empty, and the user simply wants to get the current position (which should be 0.)

A possible fix would be:

Code highlighting:

//Test for logic errors
if (!in & !out)
   return pos_type(off_type(-1));
else if((in && out) && (dir == std::ios_base::cur))
   return pos_type(off_type(-1));
else if( (in && (!(m_mode & std::ios_base::in))) || (out && (!(m_mode & std::ios_base::out))))
   return pos_type(off_type(-1));
else if ((in && this->gptr() == 0) || (out && this->pptr() == 0))
   return off == 0 ? pos_type(off_type(0)) : pos_type(off_type(-1));

comment:2 by Ion Gaztañaga, 12 years ago

Resolution: invalid
Status: newclosed

Sorry, but in MSVC7-1 it outputs -1,-1. I don't think there is any guarantee to return 0.

comment:3 by superpacko@…, 8 years ago

Cc: superpacko@… added
Resolution: invalid
Status: closedreopened
Version: Boost 1.45.0Boost 1.57.0

This is happening in vs2013 as well if you dont provide a vector or you provide an empty one, tellp() returns -1. Is no good, it forces you to initialize with a vector with something inside, instead of just relying on that default position would be 0, since it is for both input and output and theres the possibility to write on it.

comment:4 by Ion Gaztañaga, 7 years ago

The C++98 standard never guaranteed tellp() would return 0. It seems that after LWG Issue 453 returning zero is the agreed behaviour:

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#453

Several compilers and implementation seems to have fixed this so it seems logical to port it to Interprocess streams.

comment:5 by Ion Gaztañaga, 7 years ago

Resolution: fixed
Status: reopenedclosed

Fixed in:

[develop e352a84] Fixed Trac #5139 ("Initial Stream Position in Boost.Interprocess.Vectorstream")

https://github.com/boostorg/interprocess/commit/e352a84dd2d31fcad14f721c8359d25a5f9dc9fc

Note: See TracTickets for help on using tickets.