【发布时间】:2019-12-24 04:23:45
【问题描述】:
我有一个关于以下简单比较的问题:
#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:
如果两个操作数都有算术类型,通常的算术 执行转换。
6.3.1.8/1 给了我们3种可能性:
否则,如果无符号整数类型的操作数有秩 大于或等于另一个操作数的类型的等级,则 带符号整数类型的操作数转换为 无符号整数类型的操作数。
否则,如果带符号整数类型的操作数的类型可以 用无符号表示操作数类型的所有值 整数类型,然后转换无符号整数类型的操作数 为有符号整数类型的操作数的类型。
否则,两个操作数都转换为无符号整数类型 对应带符号整数类型的操作数的类型。
我们不知道ptrdiff_t 和size_t 的转化排名。此外,ptrdiff_t 通常没有对应的无符号类型(不像intptr_t 和uintptr_t)。
问题:假设ptrdiff_t的转化排名严格大于size_t,ptrdiff_t不能代表size_t的所有值。如果ptrdiff_t 没有对应的无符号整数类型,在ptrdiff_t 和size_t 之间执行比较会发生什么。这样的实现是否允许?
【问题讨论】:
-
为什么6.2.5/6不适用?它明确表示必须有一个无符号类型对应于
ptrdiff_t。我们不知道它的名字是什么,但它一定存在。 -
@rici 子句使用关键字
unsigned定义了相应的无符号类型。但根据 6.7.2/2unsigned ptrdiff_t不是有效的类型说明符。 -
St.Antario: 没有。如果
ptrdiff_t是一个类型别名,那么对应的无符号类型就是ptrdiff_t是一个别名的类型对应的无符号类型。类型别名不是不同的类型;它们是同一类型的不同名称。这就是为什么我说我们不知道对应的无符号类型的名称。我们不知道如何声明它并不意味着它不存在。 -
事实上,
ptrdiff_t可能是扩展整数类型的别名,其名称位于为实现保留的命名空间部分中。但它仍然会有对应的无符号类型。 -
size_t和ptrdiff_t的各种特质在过去二十多年的时间里被广泛讨论。在这里,在邮件列表、博客上,最重要的是在委员会提交的文件中。我认为另一场讨论不太可能揭示任何新内容。如果您对扩展整数类型的实现感兴趣,您当然可以找到它们。我不知道是否对此类类型的基本名称达成共识;我的感觉是类型别名很常见。
标签: c integer language-lawyer conversion-rank