【问题标题】:What are the usage differences between size_t and off_t?size_t 和 off_t 的用法有什么区别?
【发布时间】:2012-05-17 11:12:04
【问题描述】:

除了每种类型可以容纳的值的大小之外,size_toff_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)

【问题讨论】:

    标签: c++ linux


    【解决方案1】:

    size_t 用于对象,off_t 用于文件。

    mmap 几乎按照定义合并了这两个概念。我个人认为我会使用size_t,因为不管它是什么,映射文件也是(虚拟)内存中的一个数组。

    size_t 是标准 C++,off_t 是 Posix,off64_t 是一个 GNU 扩展,与 fopen64ftello64 等函数一起使用。我认为它应该在 64 位 GNU 系统上始终与 off_t 的类型相同,但不要在没有检查的情况下将您的公司押在上面。

    如果相关,off_t 已签名,而 size_t 未签名。但是size_t 的签名对应物是ptrdiff_t,所以当你需要一个签名类型时,它并不意味着你应该使用off_toff64_t

    【讨论】:

    • 感谢史蒂夫,这是一个很大的帮助。我想我还没有完全建立 mmap 连接这两个概念的链接。
    • 很好的答案,但到底为什么 fread() 和 fwrite() 会采用 size_t 呢?
    • 请注意,还有 ssize_t 作为 size_t 的签名对应项。
    • @NikReiman:我认为fread 采用size_t,因为关于大小的“最重要的事实”是它与缓冲区的关系。即使文件可能比系统上的内存对象大,fread/fwrite 读取/写入的对象大小也仅限于内存。但是 C 标准并不能很好地处理大文件:fseek 使用long 作为偏移量,Posix 认为这不令人满意,因此引入了fseekooff_t。也许只是因为 C 标准最初设想long 永远是最大的整数类型,但后来微软却反对。
    • 不要明确使用off64_t或64位文件函数;将-D_FILE_OFFSET_BITS=64 添加到CFLAGS 将自动将GNU 系统上的所有off_t 更改为off64_t,同时保持与不理解off64_t 的系统的兼容性。
    【解决方案2】:

    size_t 是 C++(和 C)标准的一部分,指的是 sizeof 表达式的类型。 off_t 由 Posix 标准定义,指的是文件的大小。

    【讨论】:

    • 那么使用off_t是不可移植的吗?或者 C/C++ 标准本身是否遵循 posix 标准。
    • @Als:Posix 库是对 C(和 C++)标准的一组扩展。他们添加的内容包括off_t 和使用它的文件函数,例如lseek。所以不,C/C++ 不遵守 Posix。无论如何,Posix 是一种操作系统规范,而不仅仅是一种编程语言:以及它包括的库,例如 shell 和 shell 实用程序,这些都超出了 C 标准的范围(如果你喜欢,Posix 选择了标准system 的定义省略)。
    • 如果你已经在使用mmap,那么使用off_t“是可移植的”,这也是一个Posix函数。它是可移植的 Posix 代码,而不是可移植的 C++ 代码。
    【解决方案3】:

    此方案的良好经验法则。使用任何导致您使用最少显式转换的函数签名,无论是 c 风格还是 c++ 风格。如果必须强制转换,c++ 风格会更安全,因为它可以执行的强制转换类型受到更多限制。

    这样做的好处是,如果您移植到类型不匹配的平台(无论是有符号、大小或字节序问题等),您应该在编译时捕获大部分错误,而不是在运行时。铸造是将三角形物体挤压到圆孔中的大锤方法(或多或少是您告诉编译器保持安静,我知道我在做什么)。

    尝试在运行时查找转换问题可能会很痛苦,因为它很难重现。最好在编译时而不是运行时发现问题。编译器是你的朋友。

    【讨论】:

      猜你喜欢
      • 2019-09-04
      • 2010-10-04
      • 1970-01-01
      • 2020-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-11
      相关资源
      最近更新 更多