use*_*445 74 c c++ language-lawyer
假设你有一个数组:
int array[SIZE];
Run Code Online (Sandbox Code Playgroud)
或者
int *array = new(int[SIZE]);
Run Code Online (Sandbox Code Playgroud)
C 或 C++ 是否保证array < array + SIZE,如果是,在哪里?
我知道无论语言规范如何,许多操作系统通过为内核保留虚拟地址空间的顶部来保证此属性。我的问题是语言是否也保证了这一点,而不仅仅是绝大多数实现。
举个例子,假设一个操作系统内核处于低内存中,有时会向用户进程提供虚拟内存的最高页面,以响应mmap对匿名内存的请求。如果malloc或::operator new[]直接要求mmap分配一个巨大的数组,并且数组的末尾紧靠虚拟地址空间的顶部,从而array + SIZE环绕为零,这是否等于该语言的不合规实现?
澄清
请注意,问题不是问 about array+(SIZE-1),它是数组最后一个元素的地址。那一个保证大于array。问题是关于超过数组末尾的指针,或者p+1何时p是指向非数组对象的指针(所选答案指向的标准部分明确表示以相同方式处理)。
计算器要我解释,为什么这个问题是不一样的这一个。另一个问题询问如何实现指针的总排序。另一个问题本质上归结为一个库如何实现std::less它甚至可以用于指向不同分配对象的指针,标准说只能比较相等,而不是大于和小于。
相比之下,我的问题是关于数组末尾的一个是否总是保证大于数组。我的问题的答案是或否实际上并没有改变你将如何实施std::less,所以另一个问题似乎并不相关。如果与数组末尾的比较是非法的,那么std::less在这种情况下可能只是表现出未定义的行为。(此外,通常标准库是由与编译器相同的人实现的,因此可以自由利用特定编译器的属性。)
tst*_*isl 80
如果表达式 P 指向数组对象的一个元素,而表达式 Q 指向同一个数组对象的最后一个元素,则指针表达式 Q+1 比较大于 P。
表达式array是 P。表达式array + SIZE - 1指向 的最后一个元素array,也就是 Q。因此:
array + SIZE = array + SIZE - 1 + 1 = Q + 1 > P = array
Bar*_*mar 22
指向具有较大下标值的数组元素的指针比较大于指向具有较小下标值的同一数组元素的指针
我确信 C++ 规范中有类似的东西。
这一要求有效地防止了在公共硬件上分配环绕地址空间的对象,因为实现有效实现关系运算符所需的所有簿记是不切实际的。
M.M*_*M.M 13
int *array = new(int[SIZE]);当SIZE为零时,保证不成立。
的结果new int[0]必须是一个可以0添加到它的有效指针,但array == array + SIZE在这种情况下,严格小于测试将产生false。
这是在 C++ 中定义的,来自 7.6.6.4(当前C++23 草案的p139 ):
当一个整数类型的表达式 J 与指针类型的表达式 P 相加或减去时,结果的类型为 P。
(4.1) — 如果 P 的计算结果为空指针值而 J 的计算结果为 0,则结果为空指针值。
(4.2) — 否则,如果 P 指向具有 n 个元素的数组对象 x 的数组元素 i (9.3.4.5),则表达式 P + J 和 J + P(其中 J 的值为 j)指向(可能-假设)数组元素 i + j of x 如果 0 <= i + j <= n 并且表达式 P - J 指向(可能是假设的)数组元素 i ?如果 0 <= i ? j <= n。
(4.3) — 否则,行为未定义。
请注意,4.2 明确具有“<= n”,而不是“< n”。任何大于 size() 的值都未定义,但为 size() 定义。
数组元素的排序在 7.6.9 (p141) 中定义:
(4.1) 如果两个指针指向同一个数组的不同元素,或者指向其子对象,则要求指向下标较高的元素的指针比较大。
这意味着对于 n > 0 的所有明确定义的情况,假设元素 n 将比数组本身(元素 0)更大。
C++ 中的相关规则是[expr.rel]/4.1:
如果两个指针指向同一个数组的不同元素,或者指向其子对象,则需要指向下标较高的元素的指针比较大。
上面的规则似乎只涵盖了指向数组元素的指针,并array + SIZE没有指向数组元素。然而,正如脚注中提到的,一个最后一个指针在这里被视为一个数组元素。相关的语言规则在[basic.compound]/3 中:
为指针运算的目的([expr.add])和比较([expr.rel],[expr.eq]),过去的阵列的最后一个元件的端部的指针
x的Ñ元件被认为是等同于指向假设数组元素n的指针x和类型T不是数组元素的对象被认为属于具有一个类型元素的数组T。
所以 C++ 保证array + SIZE > array(至少当SIZE > 0),以及&x + 1 > &x任何对象x。
| 归档时间: |
|
| 查看次数: |
6562 次 |
| 最近记录: |