c++ size_t或ptrdiff

时间:2022-10-28 17:01:45

If you have the following code where p is a pointer:

如果你有以下代码,p是一个指针:

p = p + strlen(p) + size_t(1);

Since strlen() and size_t are both size_t, should I cast the code to ptrdiff_t ?

因为strlen()和size_t都是size_t,所以我应该将代码转换为ptrdiff_t吗?

p = p + (ptrdiff_t)(strlen(p) + size_t(1));

If so why?

如果是这样为什么?

Thanks, Greg

谢谢,格雷格

2 个解决方案

#1


14  

std::ptrdiff_t is signed. std::size_t is unsigned. Casting strlen(p) to ptrdiff_t would make sense if p could have a negative length, which is not possible.

std::ptrdiff签署。std::size_t是无符号的。将strlen(p)转换为ptrdiff_t是有意义的,如果p的长度为负,这是不可能的。

However, that cast could overflow the resulting signed value if p is large enough (for instance, larger than 2,147,483,647 bytes on most 32-bit platforms). So it could introduce an error in your pointer arithmetic.

但是,如果p足够大(例如,在大多数32位平台上大于2,147,483,647字节),那么该转换将会溢出所产生的签名值。所以它会在你的指针算法中引入一个错误。

Best to stick with size_t here.

最好在这里使用size_t。

#2


2  

There's no need to cast to ptrdiff_t. Pointer arithmetic is well-defined for all integral types, including size_t, and if size_t wasn't big enough to hold the value, the cast to ptrdiff_t comes too late anyway.

没有必要投给ptrdiff_t。对于所有的整数类型,包括size_t,都定义了指针算法,如果size_t不够大,不足以容纳这个值,那么无论如何,向ptrdiff_t的转换都太迟了。

Here is the relevant language from the Standard (C++0x FCD, section [expr.add]):

以下是来自标准的相关语言(c++ 0x FCD, section [expr.add]):

When an expression that has integral 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 integral 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.

当一个具有整数类型的表达式被添加到或从一个指针中减去时,结果具有指针操作数的类型。如果指针操作数指向数组对象的一个元素,并且数组足够大,那么结果就会指向原始元素的一个元素偏移量,这样产生的和原始数组元素的下标的差就等于积分表达式。换句话说,如果表达式P点我th元素的数组对象,表达式(P)+ N(等价于N +(P))和(P)- N(N值N)指出,分别我+ N th−N个元素的数组对象,提供它们的存在。此外,如果表达式P指向最后一个元素的数组对象,表达(P)+ 1点过去的最后一个元素的数组对象,如果表达式问点一个过去的最后一个元素的数组对象,表达式(Q)1指向最后一个元素的数组对象。如果指针操作数和结果指向相同数组对象的元素,或者是数组对象的最后一个元素,则评估不产生溢出;否则,行为是未定义的。

#1


14  

std::ptrdiff_t is signed. std::size_t is unsigned. Casting strlen(p) to ptrdiff_t would make sense if p could have a negative length, which is not possible.

std::ptrdiff签署。std::size_t是无符号的。将strlen(p)转换为ptrdiff_t是有意义的,如果p的长度为负,这是不可能的。

However, that cast could overflow the resulting signed value if p is large enough (for instance, larger than 2,147,483,647 bytes on most 32-bit platforms). So it could introduce an error in your pointer arithmetic.

但是,如果p足够大(例如,在大多数32位平台上大于2,147,483,647字节),那么该转换将会溢出所产生的签名值。所以它会在你的指针算法中引入一个错误。

Best to stick with size_t here.

最好在这里使用size_t。

#2


2  

There's no need to cast to ptrdiff_t. Pointer arithmetic is well-defined for all integral types, including size_t, and if size_t wasn't big enough to hold the value, the cast to ptrdiff_t comes too late anyway.

没有必要投给ptrdiff_t。对于所有的整数类型,包括size_t,都定义了指针算法,如果size_t不够大,不足以容纳这个值,那么无论如何,向ptrdiff_t的转换都太迟了。

Here is the relevant language from the Standard (C++0x FCD, section [expr.add]):

以下是来自标准的相关语言(c++ 0x FCD, section [expr.add]):

When an expression that has integral 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 integral 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.

当一个具有整数类型的表达式被添加到或从一个指针中减去时,结果具有指针操作数的类型。如果指针操作数指向数组对象的一个元素,并且数组足够大,那么结果就会指向原始元素的一个元素偏移量,这样产生的和原始数组元素的下标的差就等于积分表达式。换句话说,如果表达式P点我th元素的数组对象,表达式(P)+ N(等价于N +(P))和(P)- N(N值N)指出,分别我+ N th−N个元素的数组对象,提供它们的存在。此外,如果表达式P指向最后一个元素的数组对象,表达(P)+ 1点过去的最后一个元素的数组对象,如果表达式问点一个过去的最后一个元素的数组对象,表达式(Q)1指向最后一个元素的数组对象。如果指针操作数和结果指向相同数组对象的元素,或者是数组对象的最后一个元素,则评估不产生溢出;否则,行为是未定义的。