比较 ptrdiff_t 与 size_t
Comparing ptrdiff_t with size_t
我对以下简单比较有疑问:
#define BUF_SIZE //maybe large
static char buf[BUF_SIZE];
static char *limit; // some pointer to an element of buf array
void foo(){
if(limit - buf <= sizeof buf){ //<---- This comparison
//...
}
//...
}
这里我们比较有符号的 ptrdiff_t
(左边)和无符号的 size_t
(右边)。该标准提供了以下解释
6.5.8/3
:
If both of the operands have arithmetic type, the usual arithmetic
conversions are performed.
6.3.1.8/1
给了我们 3 种可能性:
Otherwise, if the operand that has unsigned integer type has rank
greater or equal to the rank of the type of the other operand, then
the operand with signed integer type is converted to the type of the
operand with unsigned integer type.
Otherwise, if the type of the operand with signed integer type can
represent all of the values of the type of the operand with unsigned
integer type, then the operand with unsigned integer type is converted
to the type of the operand with signed integer type.
Otherwise, both operands are converted to the unsigned integer type
corresponding to the type of the operand with signed integer type.
我们不知道 ptrdiff_t
和 size_t
的转换排名。此外,ptrdiff_t
通常没有相应的无符号类型(不像 intptr_t
和 uintptr_t
)。
QUESTION:假设ptrdiff_t
的转换排名严格大于size_t
,而ptrdiff_t
不能代表所有的值size_t
。如果 ptrdiff_t
没有相应的无符号整数类型,则在 ptrdiff_t
和 size_t
之间执行比较时会发生什么情况。甚至允许这样的实现吗?
如果ptrdiff_t
的秩大于size_t
并且可以表示size_t
的所有正值。 limit - buf <= sizeof buf
没有问题。比较完成为 ptrdiff_t
.
否则ptrdiff_t
可能不代表size_t
的所有正值然后减法limit - buf
可能是下面的UB,所以比较是 moot.
J.2 Undefined behavior
The behavior is undefined in the following circumstances:
...
The result of subtracting two pointers is not representable in an object of type ptrdiff_t
(6.5.6).
Is such an implementation even allowed? (conversion rank of ptrdiff_t
is strictly greater than of size_t
and ptrdiff_t
cannot represent all the values of size_t
)
可以允许 ptrdiff_t
作为 long
和 size_t
作为 unsigned
。都是 32 位的。但也许不明智。
注意:C17 § 7.19 4 有
推荐做法
用于 size_t
和 ptrdiff_t
的类型不应具有大于 signed long int
的整数转换等级,除非实现支持足够大的对象以使其成为必要。
并不是说这在这里很适用 - 只是一个注释。
我对以下简单比较有疑问:
#define BUF_SIZE //maybe large
static char buf[BUF_SIZE];
static char *limit; // some pointer to an element of buf array
void foo(){
if(limit - buf <= sizeof buf){ //<---- This comparison
//...
}
//...
}
这里我们比较有符号的 ptrdiff_t
(左边)和无符号的 size_t
(右边)。该标准提供了以下解释
6.5.8/3
:
If both of the operands have arithmetic type, the usual arithmetic conversions are performed.
6.3.1.8/1
给了我们 3 种可能性:
Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
我们不知道 ptrdiff_t
和 size_t
的转换排名。此外,ptrdiff_t
通常没有相应的无符号类型(不像 intptr_t
和 uintptr_t
)。
QUESTION:假设ptrdiff_t
的转换排名严格大于size_t
,而ptrdiff_t
不能代表所有的值size_t
。如果 ptrdiff_t
没有相应的无符号整数类型,则在 ptrdiff_t
和 size_t
之间执行比较时会发生什么情况。甚至允许这样的实现吗?
如果ptrdiff_t
的秩大于size_t
并且可以表示size_t
的所有正值。 limit - buf <= sizeof buf
没有问题。比较完成为 ptrdiff_t
.
否则ptrdiff_t
可能不代表size_t
的所有正值然后减法limit - buf
可能是下面的UB,所以比较是 moot.
J.2 Undefined behavior
The behavior is undefined in the following circumstances:
...
The result of subtracting two pointers is not representable in an object of typeptrdiff_t
(6.5.6).
Is such an implementation even allowed? (conversion rank of
ptrdiff_t
is strictly greater than ofsize_t
andptrdiff_t
cannot represent all the values ofsize_t
)
可以允许 ptrdiff_t
作为 long
和 size_t
作为 unsigned
。都是 32 位的。但也许不明智。
注意:C17 § 7.19 4 有
推荐做法
用于 size_t
和 ptrdiff_t
的类型不应具有大于 signed long int
的整数转换等级,除非实现支持足够大的对象以使其成为必要。
并不是说这在这里很适用 - 只是一个注释。