简体   繁体   中英

What are the usage differences between size_t and off_t?

Other than the size of the values that each type can hold, what are the main differences in usage between size_t and off_t ? Is it just a convention that size_t types are used for absolute sizes and off_t types are used for offsets? Or does it go deeper than that?

I am writing a wrapper class to enable the writing of large files using mmap and I want to know what the best types are to use for their arguments. Given that I want to write to files > 4GB, I'm tempted to use size_t for everything, but is that the best practice? (or should I be using some off64_t types for certain functions?)

For example, should my writeAt function be declared as:

MMapWriter::writeAt(off64_t offset, const void* src, size_t size)

or

MMapWriter::writeAt(size_t offset, const void* src, size_t size)

size_t is for objects, off_t is for files.

mmap merges the two concepts, pretty much by definition. Personally I think I'd use size_t , since no matter what else it is, a mapped file is also an array in (virtual) memory.

size_t is standard C++, off_t is Posix, and off64_t is a GNU extension that goes with the functions fopen64 , ftello64 , etc. I think it should always be the same type as off_t on 64 bit GNU systems, but don't bet your company on that without checking.

Should it be relevant, off_t is signed whereas size_t is unsigned. But the signed counterpart to size_t is ptrdiff_t , so when you need a signed type it doesn't automatically mean you should use off_t or off64_t .

size_t is part of the C++ (and C) standards, and refers to the type of a sizeof expression. off_t is defined by the Posix standard, and refers to the size of a file.

Good rule of thumb for this scenario. Use whatever function signature that results in you using the least amount of explicit casting, be it c style or c++ style. If you have to cast, c++ style is safer as it is more limited in the types of cast it can do.

The benefit of this is if you port to a platform where the types don't match up (whether it be a signed, size or endianness issue etc.), you should catch most of the bugs at compile time, rather than at runtime. Casting is the sledgehammer approach for squeezing a triangular shaped object into a round hole (more or less your telling the compiler to keep quiet, I know what I'm doing).

Trying to find casting issues at runtime can be a pain as it can be hard to reproduce. It's better to find issues at compile-time rather than runtime. The compiler is your friend.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM