【问题标题】:Should I cast size_t to ptrdiff_t?我应该将 size_t 转换为 ptrdiff_t 吗?
【发布时间】:2015-07-28 22:55:30
【问题描述】:

我有一个 malloc 的指针数组,它形成了一个哈希表。要遍历哈希表,我会使用指针算术,例如:

node_t ** tc = table;
size_t tcs = sizeof(node_t *);
for(long i = 0; i < tableSize; tc+=tcs, ++i) { 
    // Do some stuff with *tcs location in the table.
}

问题是我应该将sizeof() 返回的size_t 转换为ptrdiff_t 以便在for 条件的增量部分正确添加吗?还是加起来有关系?

【问题讨论】:

  • 既然你已经在使用索引了,i,你也可以避开指针:for(long i = 0; i &lt; tableSize; i++) { tc = table+i; ...}或者:{ tc = &amp;table[i];}
  • OT:你应该把 i 变成 size_t
  • 其实你期望做tc += tcs的效果是什么?因为我担心它可能不会做你希望它做的事情。
  • 简而言之:tcs 在这里没用。只需执行++tc 即可转到下一个数组项。
  • @alk 这就是我问的原因。因为在我看来,OP 想要++tc(相当于tc += 1)的效果似乎是合理的,但是——除非在sizeof(char) == sizeof(node_t *) 的极其奇怪的平台上运行——他的代码会做一些不同的事情。

标签: c pointers hashtable ptrdiff-t


【解决方案1】:

您需要ptrdiff_t 来处理负值。 size_t 处理正值,例如您的示例中 sizeof 的结果,因此您不需要强制转换。

话虽如此,代码看起来很可疑:C 编译器将 struct 的大小因素考虑到您的指针算术中,因此您必须将 sizeof(node_t*) 添加到指向 node_t 的双指针的事实可能是错误。如果要前进到指针数组中的下一个指针,请将1 添加到该指针的当前值。编译器足够聪明,可以根据指针的类型为您将 1 乘以 sizeof(*ptr)

【讨论】:

    【解决方案2】:

    没有。你不需要。

    指针运算是根据指针T *类型 执行的。添加size_t 不会影响指针运算,因为增量是使用sizeof(T) 完成的。

    引用标准(C11草案):

    6.5.6 加法运算符

    当一个整数类型的表达式被添加或减去时 从一个指针,结果具有指针操作数的类型。如果 指针操作数指向数组对象的一个​​元素,而数组 足够大,结果指向一个元素偏移量 原始元素使得下标的差异 结果和原始数组元素等于整数表达式。 换句话说,如果表达式 P 指向一个 数组对象,表达式 (P)+N(等价于 N+(P))和 (P)-N (其中 N 的值为 n)分别指向第 i+n 个和 数组对象的第 i-n 个元素,前提是它们存在。此外,如果 表达式 P 指向数组对象的最后一个元素, 表达式 (P)+1 指向数组对象的最后一个元素, 如果表达式 Q 指向数组的最后一个元素 对象,表达式 (Q)-1 指向数组的最后一个元素 目的。如果指针操作数和结果都指向元素 相同的数组对象,或数组的最后一个元素 对象,评估不应产生溢出;否则, 行为未定义。如果结果指向最后一个元素 数组对象,它不能用作一元的操作数 * 被评估的运算符。

    另一方面,将size_t 转换为ptrdiff_t 可能导致错误代码,因为ptrdiff_t 是有符号类型,而size_t 是无符号类型。因此,如果结果值大于ptrdiff_t 可以容纳的值,那么就有问题了。简而言之,将任何整数类型添加到指针类型时,指针算术是明确定义的,您根本不需要这样的强制转换。

    【讨论】:

      【解决方案3】:

      这里不需要ptrdiff_t,因为周围没有指针差异。

      你可能想要的是:

      for (node_t ** tc = table; tc < (table + tableSize); ++tc) {
        ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-16
        • 1970-01-01
        • 2019-11-09
        • 2013-12-02
        • 1970-01-01
        • 2020-05-01
        • 2011-12-31
        • 2019-01-26
        相关资源
        最近更新 更多