std::streampos, std::streamoff and std::streamsize to long long int?

Vincent picture Vincent · Oct 8, 2012 · Viewed 15.1k times · Source

To measure position/offsets/size of streams, the standard specify std::streampos, std::streamoff and std::streamsize, but they are implementation defined.

How to convert these types to long long int in a secure and portable way ? (for example to measure a file size and inject it in a function that take a long long int as argument)

Answer

Nicol Bolas picture Nicol Bolas · Oct 8, 2012

Well, as far as C++98/03 is concerned, there is no long long int. So I'll assume you're asking about C++11.

The streamsize and streamoff are required to be typedefs of an integral type (streampos is not an integer, so you won't be passing that to anything that takes a long long). Since integral types are basic types, they can only be defined by either C++ or as a compiler-specific definition.

Thus, the only question is this: are these typedefs larger than long long? All integral types are convertible to a larger or equal-sized type (signed/unsigned notwithstanding, but all of the types here are signed, so no problem). But if it is larger... what are you going to do about it?

Assuming you can't change the signature of the function you are "injecting" it into (because if you could, there's no reason not to just take streamsize as the parameter type and thus avoid the problem), you don't have any options. You have a data value that is larger than what the function takes. There's no way of getting around it here.

You can perform a static_cast into a long long to shut the compiler up, but this won't help if the actual size can't fit in a long long.

Ultimately, this is an intractable problem. You have a function that takes a parameter which is potentially too small for what you're passing. The most you can do is detect when it might be a problem via a static_assert. Something like this:

static_assert(sizeof(std::streamsize) <= sizeof(long long), "Oops.");

To be honest, I wouldn't worry about it. Odds are good that long long will be the largest integral size that your compiler natively supports.