Opened 10 years ago

Closed 10 years ago

Last modified 9 years ago

#7873 closed Bugs (fixed)

C4244 in basic_binary_iprimitive.hpp due to std::size_t and std::streamsize type difference

Reported by: Hamp <boost@…> Owned by: Robert Ramey
Milestone: To Be Determined Component: serialization
Version: Boost 1.50.0 Severity: Cosmetic
Keywords: Cc:

Description

With Visual Studio 2010 a C4244 warning appears in basic_binary_iprimitive.hpp.

boost/archive/basic_binary_iprimitive.hpp(181): warning C4244: 'argument' : conversion from 'std::streamsize' to 'size_t', possible loss of data

The offending line is the last one in the function, with (count - s)

template<class Archive, class Elem, class Tr>
inline void
basic_binary_iprimitive<Archive, Elem, Tr>::load_binary(
    void *address, 
    std::size_t count
){
    // note: an optimizer should eliminate the following for char files
    BOOST_ASSERT(
        static_cast<std::streamsize>(count / sizeof(Elem)) 
        <= boost::integer_traits<std::streamsize>::const_max
    );
    std::streamsize s = static_cast<std::streamsize>(count / sizeof(Elem));
    std::streamsize scount = m_sb.sgetn(
        static_cast<Elem *>(address), 
        s
    );
    if(scount != s)
        boost::serialization::throw_exception(
            archive_exception(archive_exception::input_stream_error)
        );
    // note: an optimizer should eliminate the following for char files
    BOOST_ASSERT(count % sizeof(Elem) <= boost::integer_traits<std::streamsize>::const_max);
    s = static_cast<std::streamsize>(count % sizeof(Elem));
    if(0 < s){
//        if(is.fail())
//            boost::serialization::throw_exception(
//                archive_exception(archive_exception::stream_error)
//        );
        Elem t;
        scount = m_sb.sgetn(& t, 1);
        if(scount != 1)
            boost::serialization::throw_exception(
                archive_exception(archive_exception::input_stream_error)
            );
        std::memcpy(static_cast<char*>(address) + (count - s), &t, s);
    }
}

where count is a passed-in std::size_t and s is a local std::streamsize.

Ticket #3755 discusses a related issue in the asserts where a signed/unsigned comparison took place. This was resolved by a static_cast in the assert.

For Visual Studio 2010, x86, and both Release and Debug, the following effective typedefs apply

typedef __int64 streamsize;
typedef _unsigned int size_t;

Since s is set by count, there does not seen to be a risk of overflowing s. Is there any way to prevent the warning?

I check the current trunk and the issue would still exist.

Change History (4)

comment:1 by anonymous, 10 years ago

I'm also experiencing this. Really annoying warning!

comment:2 by Robert Ramey, 10 years ago

Resolution: fixed
Status: newclosed

comment:3 by yochait@…, 10 years ago

An easy "fix" for this if you don't have a fixed version of boost:
Just ignore the warnings in the specific files.

#pragma warning (push)
#pragma warning( disable : 4244 )

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>

#pragma warning (pop)

comment:4 by anonymous, 9 years ago

Same issue in dynamic_bitset.hpp in Boost 1_55_0

Note: See TracTickets for help on using tickets.