如果您有以下代码,其中p是指针:
p = p + strlen(p) + size_t(1);
由于strlen()
和size_t
都是size_t
,我应该将代码转换为ptrdiff_t
吗?
p = p + (ptrdiff_t)(strlen(p) + size_t(1));
若是,为什么?
谢谢, 格雷格
答案 0 :(得分:18)
std::ptrdiff_t已签名。 std::size_t未签名。如果strlen(p)
可能有负长度,那么将ptrdiff_t
投射到p
会有意义,这是不可能的。
但是,如果p
足够大(例如,在大多数32位平台上大于2,147,483,647字节),那么强制转换可能会溢出结果符号值。所以它可能会在你的指针算术中引入一个错误。
最好坚持使用size_t
。
答案 1 :(得分:2)
无需转发ptrdiff_t
。指针运算是针对所有整数类型定义的,包括size_t
,如果size_t
不足以容纳值,那么转换为ptrdiff_t
无论如何都来得太晚了。
以下是标准的相关语言(C ++ 0x FCD,[expr.add]
部分):
当一个表达式有积分时 类型被添加到或从中减去 指针,结果有类型 指针操作数。如果指针 操作数指向一个元素 数组对象,数组很大 够了,结果指向了 元素偏离原始 元素这样的差异 结果和的下标 原始数组元素等于 积分表达。换一种说法, 如果表达式P指向i - 数组对象的元素,表达式(P)+ N(等效地, N +(P))和(P)-N(其中N具有 值n)分别指向 i + n和i - n的元素 数组对象,只要它们存在。 而且,如果表达P点 到数组的最后一个元素 对象,表达式(P)+1分 一个超过数组的最后一个元素 对象,如果表达式Q指向 一个超过数组的最后一个元素 对象,表达式(Q)-1指向 数组对象的最后一个元素。 如果指针操作数和 结果指向相同的元素 数组对象,或者是最后一个对象 数组对象的元素, 评估不得产生 溢出;否则,行为是 未定义。