问题描述
我总是读到指针算术是定义的,只要你不离开数组的边界.我不确定我是否完全理解这意味着什么,我有点担心.因此这个问题.
I am always reading that pointer arithmetic is defined as long as you don't leave the bounds of the array. I am not sure I completely understand what this means and I was a little worried. Hence this question.
假设我从一个指向数组开头的指针开始:
Suppose I start with a pointer to the beginning of an array:
int *p = (int*) malloc(4 * sizeof(int));
现在我创建了两个位于数组边界之外的新指针:
Now I create two new pointers that lie outside the bounds of the array:
int *q = p + 10;
int *r = p - 2;
现在指针 q-10
, q-9
, ..., r+2
, r+3
等都位于数组的边界内.它们有效吗?例如,r[3]
保证得到与p[1]
相同的结果吗?
Now the pointers q-10
, q-9
, ..., r+2
, r+3
, and so on all lie inside the bounds of the array. Are they valid? For example, is r[3]
guaranteed to give the same result as p[1]
?
我已经做了一些测试并且它有效.但我想知道这是否包含在通常的 C 规范中.具体来说,我使用的是 Visual Studio 2010、Windows,并且我正在使用本机 C(不是 C++)进行编程.我被覆盖了吗?
I have done some testing and it works. But I want to know if this is covered by the usual C specifications. Specifically, I am using Visual Studio 2010, Windows, and I am programming in native C (not C++). Am I covered?
推荐答案
您所做的工作适用于您正在使用的实现以及最流行的实现,但它不符合 C.正如 chris 所引用的,
What you're doing works on the implementation you're using, as well as most popular implementations, but it's not conforming C. As chris cited,
>
§6.5.6/8:如果指针操作数和结果都指向同一个数组对象的元素,或者数组对象的最后一个元素之后,求值不会产生溢出;否则,行为未定义
未定义的事实在未来可能会变得越来越重要,更高级的静态分析允许编译器将此类代码转换为致命错误,而不会产生运行时成本.
The fact that it's undefined will probably become increasingly important in the future, with more advanced static analysis allowing compilers to turn this kind of code into fatal errors without incurring runtime cost.
顺便说一下,在未定义的同一数组中减去指针的历史原因是分段内存(想想 16 位 x86;熟悉它的人会想到大"内存模型).虽然指针可能涉及段和偏移组件,但编译器可以只对偏移组件进行算术运算,以避免运行时成本.这使得不在同一段中的指针之间的算术无效,因为差异的高位"丢失了.
By the way, the historical reason for subtracting pointers not within the same array being undefined is segmented memory (think 16-bit x86; those familiar with it will want to think of the "large" memory model). While pointers might involve a segment and offset component, a compiler could do the arithmetic just on the offset component to avoid runtime cost. This makes arithmetic between pointers not in the same segment invalid since the "high part" of the difference is lost.
这篇关于指针算术在数组之外仍然有效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!