我应该将size_t转换为ptrdiff_t吗?

时间:2015-05-17 11:09:04

标签: c pointers hashtable ptrdiff-t

我有一个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.
}

问题是我应该将size_t返回的sizeof()投放到ptrdiff_t,以便在for条件的增量部分中正确添加吗?或者甚至对添加有影响吗?

3 个答案:

答案 0 :(得分:2)

没有。你不需要。

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

引用标准(C11草案):

6.5.6加法运算符

  

添加或减去具有整数类型的表达式时   从指针开始,结果具有指针操作数的类型。如果   指针操作数指向数组对象的元素和数组   足够大,结果指向一个偏离的元素   原始元素使得下标的差异   结果和原始数组元素等于整数表达式。   换句话说,如果表达式P指向一个的第i个元素   数组对象,表达式(P)+ N(等效地,N +(P))和(P)-N   (其中N具有值n)分别指向第i + n和第i   数组对象的第i个元素,只要它们存在即可。而且,如果   表达式P指向数组对象的最后一个元素,即   表达式(P)+1指向数组对象的最后一个元素,   如果表达式Q指向一个数组的最后一个元素   对象,表达式(Q)-1指向数组的最后一个元素   宾语。如果指针操作数和结果都指向元素   相同的数组对象,或一个超过数组的最后一个元素   对象,评估不得产生溢出;否则,   行为未定义。如果结果指向最后一个元素   对于数组对象,它不应该用作一元*的操作数   被评估的运算符。

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

答案 1 :(得分:2)

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

有了这个说法,代码看起来很可疑:C编译器会将struct的大小计算到你的指针算术中,所以你必须将sizeof(node_t*)添加到node_t到{{}的双指针1}}可能是个错误。如果要进入指针数组中的下一个指针,请将1添加到该指针的当前值。根据指针的类型,编译器足够聪明,可以为1乘以sizeof(*ptr)

答案 2 :(得分:1)

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

你可能想要的是:

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