除了每种类型可以容纳的值的大小之外,size_t
和off_t
之间用法的主要区别是什么?仅仅是size_t
类型用于绝对大小并且off_t
类型用于偏移的惯例吗?或者它比那更深?
我正在编写一个包装类来使用mmap
来编写大文件,我想知道用于参数的最佳类型是什么。鉴于我想写文件> 4GB,我很想用size_t来做所有事情,但这是最好的做法吗? (或者我应该为某些功能使用某些off64_t
类型吗?)
例如,我的writeAt
函数应该声明为:
MMapWriter::writeAt(off64_t offset, const void* src, size_t size)
或
MMapWriter::writeAt(size_t offset, const void* src, size_t size)
答案 0 :(得分:49)
size_t
用于对象,off_t
用于文件。
mmap
合并了这两个概念,几乎就是定义。我个人认为我使用size_t
,因为无论它是什么,映射文件也是(虚拟)内存中的数组。
size_t
是标准C ++,off_t
是Posix,off64_t
是GNU扩展,与fopen64
,ftello64
等函数一起使用。 认为它应该总是与64位GNU系统上的off_t
类型相同,但不要在没有检查的情况下打赌你的公司。
如果相关,则off_t
已签名,而size_t
未签名。但size_t
的签名对象为ptrdiff_t
,因此当您需要签名类型时,它并不意味着您应该使用off_t
或off64_t
。
答案 1 :(得分:12)
size_t
是C ++(和C)标准的一部分,指的是sizeof
表达式的类型。 off_t
由Posix标准定义,并指文件的大小。
答案 2 :(得分:0)
这种情况的经验法则很好。使用任何导致您使用最少量显式转换的函数签名,无论是c样式还是c ++样式。如果你必须进行强制转换,那么c ++样式会更安全,因为它可以做更多限制。
这样做的好处是,如果您移植到类型不匹配的平台(无论是签名,大小还是字节序等问题),您应该在编译时捕获大部分错误,而不是在运行时。铸造是用于将三角形物体挤压成圆孔的大锤方法(或多或少地告诉编译器保持安静,我知道我在做什么)。
尝试在运行时查找转换问题可能会很麻烦,因为它很难重现。最好在编译时而不是运行时查找问题。编译器是你的朋友。