【问题标题】:Does size_t have the same size and alignment as ptrdiff_t?size_t 的大小和对齐方式是否与 ptrdiff_t 相同?
【发布时间】:2020-09-08 03:56:15
【问题描述】:

在我的平台上(我认为在大多数平台上)std::size_tstd::ptrdiff_t 具有相同的大小和相同的对齐方式。有没有不正确的平台?简而言之:是标准要求的吗?

【问题讨论】:

    标签: c++ language-lawyer size-t ptrdiff-t


    【解决方案1】:

    简而言之:是标准要求的吗?

    没有。唯一的要求来自[support.types.layout]/2,它是:

    ptrdiff_t 类型是实现定义的有符号整数类型,可以保存数组对象中两个下标的差异,如 [expr.add] 中所述。

    paragraph 4

    [ 注意:建议实现为 ptrdiff_t 和 size_t 选择整数转换等级不大于signed long int 的类型,除非需要更大的大小来包含所有可能的值。 ——尾注]

    但注释是非规范性的,它只是一个建议,而不是要求。


    std::size_t 定义为

    类型 size_t 是实现定义的无符号整数类型,它大到足以包含任何对象 ([expr.sizeof]) 的大小(以字节为单位)。

    paragraph 3中,也没有要求必须相同。

    【讨论】:

    • 您可能还需要注意size_t 的要求,它紧跟在您为ptrdiff_t 链接的要求之后。
    • @Peter 已添加到答案中
    • ptrdiff_t 不是size_t 的签名版本在哪个平台上?
    • @MaximEgorushkin AFAIK,没有。也就是说,不能保证适用于所有系统。
    • 16 位系统(没有庞大的代码模型)呢?在这种情况下,size_t 自然是 16 位,但您希望 ptrdiff_t 更大,以便您可以拥有大小在 32K 和 64K 之间的 char 数组。事实上,en.cppreference.com/w/cpp/types/ptrdiff_t 有一条注释,C++11 要求 ptrdiff_t 至少为 17 位宽。
    【解决方案2】:

    标准没有要求。

    请注意,当前的英特尔处理器具有 48 位指针。

    所以我个人认为,为std::size_t 设计一个 64 位 unsigned 并为std::ptrdiff_t 设计一个 49 位有符号类型并不太牵强。虽然这样的方案实施起来会很头疼。

    更有趣的是,一旦芯片组发展为具有 64 位指针(我们离必要的还有一段距离),大概std::ptrdiff_t 将必须至少为 65 位!因此,我个人记住,sizeof(std::ptrdiff_t) 可能大于sizeof(std::size_t)

    【讨论】:

    • 在引擎盖下,指针仍然是 64 位。 x86_64 要求前 16 位是第 47 位的副本。ARM64 可以忽略可用于标记的 64 位指针中的最高字节。
    • @MaximEgorushkin:我正要带着矛盾介入,但我注意到,和我一样,你是一个童年的 Z80 程序员!我编写了一些“精灵”代码,使其成为一些商业游戏:其中之一是巫术。注意异或的可怕用法!
    • 你是说Z80是16位地址的8位处理器吗? xor 是当时许多复制保护/代码加密的基础,尤其是对于未记录的 R 寄存器,您不能只在调试器中单步执行来解密代码。那时我可能玩过巫术!真正的高性能代码使用push 在屏幕上绘图,因为它是存储单词并移动到上一个写入位置的最快方式。
    【解决方案3】:

    在我的平台上...std::size_tstd::ptrdiff_t 大小相同

    这如何合规?

    C 有(我相信 C++ 继承了 - 如果不让我知道删除)作为 § J.2 中的 UB:

    两个指针相减的结果无法在 ptrdiff_t (6.5.6) 类型的对象中表示。"

    这允许ptrdiff_t 的类型成为未签名size_t 的签名对应项。
    当这样配对没有填充时,

    char a[PTRDIFF_MAX + (size_t)1];         // OK with enough memory in the location needed
    size_t size_a = sizeof a;                // OK             
    size_t diff0 = &a[sizeof a - 1] - &a[0]; // OK
    ptrdiff_t diff1 = &a[sizeof a] - &a[0];  // UB
    ptrdiff_t diff2 = %a[0] - &a[sizeof a];  // UB
    

    故事的寓意:指针减法的麻烦(结果类型:ptrdiff_t可能在数组元素计数超过PTRDIFF_MAX时开始。

    【讨论】:

      猜你喜欢
      • 2016-03-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 2018-05-08
      • 2019-01-26
      • 1970-01-01
      • 2012-11-30
      • 2013-04-05
      相关资源
      最近更新 更多