Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can [std::streampos] be converted to [size_t] implicitly?

#include <fstream>

int main()
{
    std::ifstream fin{ "" };
    size_t n = fin.tellg(); // ok
}

The code compiles ok. However, according to cppreference, I find fin.tellg() is a type of std::fpos, which doesn't define the ability to convert itself to size_t implicitly.

Any explanations?

like image 592
xmllmx Avatar asked Jan 18 '17 08:01

xmllmx


2 Answers

You are right about the fact that it returns an std::fpos. Now let's look at how it's defined:

template<class _Statetype>
    class fpos {<...>}

fpos also does have a conversion operator for converting into the streamoff type which is "stream offset" type:

__CLR_OR_THIS_CALL operator streamoff() const
    {   // return offset
    return ((streamoff)(_Myoff + _FPOSOFF(_Fpos)));
    }

On my machine streamoff happens to be defined as typedef _Longlong streamoff;, I would believe it's something similar on your machine. This is why it can be converted to type_t, however nothing prevents it from being larger than type_t, so be careful.

like image 146
SingerOfTheFall Avatar answered Oct 24 '22 01:10

SingerOfTheFall


"OK" on your platform. Not necessarily OK on all platforms. Whether in practice that means much depends on the circumstances. For example, on a 32-bit system, the file may be 4GB or larger, and thus not fit in the 32-bit size_t, where std::fpos is a 64-bit value and does hold the size of the file.

If the n is used to determine the length of the file or some such, serious problems may occur if you misjudge the total size - overwriting old data, or if you load the file and then save it based on that, you'd lose some or all of the data.

like image 3
Mats Petersson Avatar answered Oct 24 '22 02:10

Mats Petersson