我应该将 size_t 转换为 ptrdiff_t 吗?

Should I cast size_t to ptrdiff_t?

我有一个 malloc 的指针数组,它形成一个散列 table。要遍历散列 table 我会使用指针算法,例如:

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 条件的增量部分正确添加?或者它甚至对添加有影响吗?

没有。你不需要。

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

完成的

引用标准(C11草案):

6.5.6 加法运算符

When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist. Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.

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

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

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

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

您可能想要的是:

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