How do all the different types of sizes relate to each other?

I currently have a script in which I want to check if writing a given line to filestream will grow the file outside of a given size (this is used to rotate the log). Now std::ofstream::tellp() returns streampos , but std::string::size() returns a size_t . The effect is that this does not work:

 out_stream.tellp() + string.size() < limit 

because, apparently, there is an ambiguous operator + overload for these types. This leads me to two questions:

  • How can I eliminate the above ambiguity?
  • How are all the different types ( size_t , streamsize , streampos , streamoff ) related to each other? When can they be safely converted and what are the possible traps. I am generally confused by these types. All I know is that they are implementation dependent and that they provide certain guarantees (for example, size_t always large enough to hold the size of a large object that will fit into memory in the architecture for which the application was compiled), but What are the compatibility guarantees of these types (see the example above or comparing streamsize with a size_t )?
+8
c ++
source share
4 answers

You should be able to convert the result from tellp to std::string::size_type by casting.

static_cast<std::string::size_type>(out_stream.tellp()) + string.size() < limit

EDIT: This is safe because your stream offset will never be negative and will safely convert to unsigned value.

+4
source share

The real question is: what type of limit? The usual way to test, if there is still room, as a rule: limit - out_stream.tellp ()> = string.size () But you must make sure that the restriction has a type from which out_stream.tellp () can be subtracted.

In theory, flows cannot be convertible and comparable to an integral of a type, or that, converted to an integral type, it gives significant information. And for this, subtraction of support or comparison was required for this. In practice, I don’t think that you have to worry too much about converting to an existing integral type and monotony (although it’s possible on some exotic mainframe ...). But you cannot be sure that arithmetic will work with it, so I would prefer to convert it explicitly to a stream (which, as guaranteed, is a signed integral type). (Regardless of how you approach the problem, you will have to decide that string.size () returns the size_t that is required to be unsigned, while streamsize is required to sign.)

As for your second question: size_t is a typedef for an unsigned integral type large enough to indicate the size of any possible object, streamsize is a typedef for a signed integral type large enough to indicate the size of the "object" in the stream, streamoff is a typedef for an integral type capable of indicating the position of the byte in the file and streampos is a typedef for fpos, where there is something of a type that can be used to maintain state in the case of a multibyte stream. The standard has very few requirements regarding the relationship between them (and some of the few that it does are mathematically impossible to realize), so you are pretty much on your own.

+3
source share

I believe the standard says that streamsize implementation specific, so there is no help. For a practical answer, you can check the headers where they are typedef ed.

Given that size_t can be 4 bytes, while your application is probably running on a stream longer than 4 GB, I believe that you should use a class of a known type for interoperability for a sealed solution.

Of course, if you know (possibly with a compile time statement) that size_t or streamsize is 8 bytes long, you can use this type directly. If you have a stream whose length does not match 8 bytes, you have more serious problems than casting to the correct type.

+1
source share

If you have large sizes, this is not unsigned long long the best you can get. If it's not big enough, what else?

0
source share

All Articles