bec*_*cko 9 c arrays pointers language-lawyer
我总是在读取指针算法的定义,只要你不离开数组的边界即可.我不确定我完全理解这意味着什么,我有点担心.因此这个问题.
假设我从一个指向数组开头的指针开始:
int *p = (int*) malloc(4 * sizeof(int));
现在我创建了两个位于数组边界之外的新指针:
int *q = p + 10;
int *r = p - 2;
现在指针q-10,q-9..., ,r+2,r+3等所有的谎言数组的边界内.它们有效吗?例如,r[3] 保证给出相同的结果p[1]?
我做了一些测试,它的工作原理.但我想知道这是否适用于通常的C规范.具体来说,我使用的是Visual Studio 2010,Windows,而且我使用的是原生C(非C++)编程.我被覆盖了吗?
你正在做的是你正在使用的实现,以及最流行的实现,但它不符合C.正如克里斯所引用的,
§6.5.6/ 8:如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义
它未定义的事实在未来可能会变得越来越重要,更先进的静态分析允许编译器将这种代码转化为致命错误,而不会产生运行时成本.
顺便说一句,减去不在同一数组中的指针未定义的历史原因是分段存储器(想想16位x86;熟悉它的人会想到"大"存储器模型).虽然指针可能涉及段和偏移组件,但编译器可以仅对偏移组件执行算术以避免运行时成本.这使得不在同一段中的指针之间的算术无效,因为差异的"高部分"丢失.
根据C11标准,§6.5.6/ 8(我在上下文中放置了第一部分):
当一个具有整数类型的表达式被添加到指针或从指针中减去时
......
如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不得产生溢出; 否则,行为未定义.
因此,在数组之外而不是在结束之外的结果是未定义的行为.